Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
153 views
in Technique[技术] by (71.8m points)

javascript - Safari bug :first-child doesn't update display:block when items are removed with JS

With a list of items where all are hidden by default, the first li has a display of block. The problem is that this won't update if the first element is removed, de facto making a new first-child which should be displayed. In Safari the new li that should show is not displayed.

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'));
});

See the fiddle: http://jsfiddle.net/BFTan/1/

In all other browsers clicking the button will cycle through the items but in Safari nothing updates.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This appears to be a problem with display: none and objects removed from the document tree which manifests itself when you use :first-child, rather than a problem intrinsic to Safari's handling of the :first-child selector itself.

Either way, this is definitely a bug. jQuery doesn't destroy the object even when you detach it (and its contents) from its parent, but when detaching an element from its parent it should no longer be the nth child of its parent for whatever value of n, so the next element that becomes the first child should match :first-child accordingly.

If you change :first-child in your code to :not(:last-child), like this, such that you have two elements displaying at a time, you'll notice in Safari when you click the button the first element disappears, leaving the second element intact (as well as the third which is still hidden).

I also found that if you add a new empty rule with the :empty selector on the list itself:

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

Everything will suddenly work correctly in Safari. Even more bizarre is that this workaround does not work with any other level 3 pseudo-class. It only works with :empty or :not(:empty).


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...