Webkit (Chrome / Safari) не обновляет отображение при изменении выбранного пользовательского атрибута

#html #css

#HTML #css

Вопрос:

Рабочий пример:http://jsfiddle.net/JVVcA /

HTML:

 <fieldset id="data-page">
    <legend>data-page</legend>
    <button rel="page1">Highlight page one</button>
    <button rel="page2">Highlight page two</button>
    <div data-page="page1">
        <h1 id="page1">Page one</h1>
        <h1 id="page2">Page two</h1>
    </div>
</fieldset>

<fieldset id="class">
    <legend>class</legend>
    <button rel="page3">Highlight page three</button>
    <button rel="page4">Highlight page four</button>
    <div class="page3">
        <h1 id="page3">Page three</h1>
        <h1 id="page4">Page four</h1>
    </div>
</fieldset>
  

CSS:

 fieldset { border: 1px solid #aaa; padding: 5px; }

h1 { background-color: white; }
div[data-page="page1"] h1#page1 { background-color: pink; }
div[data-page="page2"] h1#page2 { background-color: pink; }
div.page3 h1#page3 { background-color: cyan; }
div.page4 h1#page4 { background-color: cyan; }
  

JS:

 $('#data-page button').click(function(){
    var rel = $(this).attr('rel');
    $(this).siblings("div").attr('data-page', rel);
});

$('#class button').click(function(){
    var rel = $(this).attr('rel');
    $(this).siblings("div").attr('class', rel);
});
  

Начальная загрузка:

После нажатия «Выделить вторую страницу» и «Выделить четвертую страницу» в Webkit (в частности, в Google Chrome для стабильной работы Windows 7):

После выполнения того же самого в Firefox:

Как вы можете видеть, data-page селектор отлично работает при первоначальном рендеринге страницы, но когда DOM управляется «на лету», стили, определенные [data-page="???"] селектором CSS, не затрагиваются соответствующим образом. Сравните это с ситуацией с селекторами классов. Когда классы меняются «на лету», стили меняются, как и ожидалось.

Возможно, с этим связано замечание о том, что я сталкивался со случаями при использовании этого селектора атрибутов в сочетании с CSS-переходами, когда происходит аналогичное отсутствие реакции, но в этих случаях нажатие в другом месте страницы, перемещение мыши по кругу или просто ожидание немного в конечном итоге приводит к ожидаемому изменению.

Итак, есть ли способ обойти это, кроме как просто поднять руки и не использовать атрибуты data-page стиля?

Комментарии:

1. В качестве дополнительного примечания, ваш jsFiddle корректно работает в Chrome dev.

2. Это работает в Chrome 14.0.835.163 m на Windows XP.

Ответ №1:

Это та же проблема, которая применяется для ~ или нескольких селекторов и псевдоклассов в webkit: такого рода селекторы отображаются только один раз, и в последний раз, когда я проверял соответствующие отчеты об ошибках в трекере webkit, они заявили, что все работает так, как задумано.

Но некоторые люди нашли исправление, но это действительно накладно: добавить свойство always-reflowing в body, поэтому его необходимо добавлять только к тем элементам, где что-то меняется, наборы полей divs внутри для вашего примера.

Итак, есть исправленная ошибка: http://jsfiddle.net/JVVcA/2 /

И это стили для устранения таких проблем:

 /* The `fixing` animation */
@-webkit-keyframes bugfix { from { padding: 0; } to { padding: 0; } }
.anElementToFix { -webkit-animation: bugfix infinite 1s; }
  

Обратите внимание, что вы должны добавить исправление к элементу, атрибут которого может быть изменен, а не к элементам, на которые нацелен селектор.

Комментарии:

1. Спасибо за решение. Можно было бы задаться вопросом, почему, если это «работает как задумано», такая же проблема не возникала в версиях Chrome для Windows. В то же время, я чувствую, что, возможно, сейчас самое подходящее время отказаться от семантичности и перейти к более эффективному решению с использованием классов.

Ответ №2:

Моя версия обходного пути.

 $('#data-page button').click(function(){
    var rel = $(this).attr('rel');
    var my_div = $(this).siblings("div");
    my_div.attr('data-page', rel);
    var my_html = my_div.html();
    my_div.html(my_html);
});

$('#class button').click(function(){
    var rel = $(this).attr('rel');
    $(this).siblings("div").attr('class', rel);
});
  

Ответ №3:

Запуск анимации кажется чрезмерно дорогостоящим.

Благодаря Золтану Оле я нашел гораздо более элегантное, краткое и эффективное решение.

Просто переключите бессмысленный класс в теле. Это приведет к повторной оценке содержащихся в нем селекторов.

Вам даже не нужно определять этот класс в CSS. Простое применение этого заставляет Safari просматривать страницу, переоценивая информацию.

Каждый раз, когда вы меняете соответствующий атрибут, включайте или выключайте этот класс, чтобы принудительно выполнить повторную оценку.

 // change some attribute
$(".blah").attr("state", "otherState");   // example of changing an attribute (your app will be different)
$('body').toggleClass('zoltan');    // THIS IS THE LINE YOU MUST ADD EVERY TIME YOU CHANGE THE ATTRIBUTE
  

Комментарии:

1. комментарий к понижающему голосованию был бы милым. я знаю некрасивое обходное решение, но это небольшое некрасивое обходное решение с контролируемой стоимостью.