Ошибка Safari: первый ребенок не обновляет отображение: блокирует удаление элементов с помощью JS

Со списком элементов, где все скрыты по умолчанию, первый li имеет display of block. Проблема в том, что это не будет обновляться, если первый элемент будет удален, де-факто создаст новый первый ребенок, который должен отображаться. В Safari новый li, который должен отображаться, не отображается.

HTML

<ul class="list">
  <li class="item">1</li>
  <li class="item">2</li>
  <li class="item">3</li>
</ul>
<button>click me </button>

CSS

.list .item { display: none } 
.list .item:first-child { display:block}

JS

$('button').on('click', function(e) {
  $('ul li:first').remove().appendTo($('ul'));
});

Смотрите скрипту: http://jsfiddle.net/BFTan/1/

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

Ответы

Ответ 1

Это, по-видимому, проблема с display: none и объектами, удаленными из дерева документов, которые проявляются при использовании :first-child, а не как проблема, связанная с обработкой Safari селектора :first-child.

В любом случае, это определенно ошибка. jQuery не уничтожает объект, даже если вы его отделите (и его содержимое) от его родителя, но при отсоединении элемента от его родителя он больше не должен быть n-м дочерним элементом его родителя для любого значения n, поэтому следующий элемент который становится первым, должен соответствовать :first-child соответственно.

Если вы измените :first-child в своем коде на :not(:last-child), например this, чтобы вы отображали одновременно два элемента, вы заметите в Safari, когда вы нажимаете кнопку, первый элемент исчезает, оставляя второй элемент неповрежденным (а также третьим, который все еще скрыт).

Я также обнаружил, что если вы добавите новое пустое правило с помощью селектора :empty в самом списке:

/* Or even .list:empty even though it not actually empty */
.list:not(:empty) {}

Все будет внезапно работать правильно в Safari. Еще более странно, что это обходное решение не работает с любым псевдоклассом уровня 3. Он работает только с :empty или :not(:empty).