Blackbing Playground

jQuery element.toggle的陷阱

jQuery有個很方便的function:toggle,可以讓元素做指定的切換動作,若不指定任何參數,則可以讓元素做很簡單的隱藏、顯示的切換,很是方便。If they are shown, toggle makes them hidden (using the hide method). If they are hidden, toggle makes them shown (using the show method).

但今天突然發現在針對大量元素的隱藏顯示時,這個function效能很差。

看範例(另開視窗)

第一種方式是click之後再跑一個for loop讓所有元素做toggle,很明顯的這個方式效能很差(用IE開更是慢到離譜~)。範例裡頭的element有600個。

1
2
3
4
5
6
function dividend_toggle(){
$('.dividend').toggle();
dividend_toggled = !dividend_toggled;
$('#toggler').html(dividend_toggled?'hide':'show');
}
$('#toggler').click(dividend_toggle);

第二種方式是利用toggle的切換直接決定show and hide,效能上就比第一種方式好多了。

1
2
3
4
5
6
7
$('#toggler2').toggle(function(){
$('td.dividend').hide();
$(this).html('show');
}, function(){
$('td.dividend').show();
$(this).html('hide');
});

其實這是一個觀念上的陷阱,toggle()交由元素自己判斷顯示還是隱藏,在很多場合是非常方便的,但元素一多就會發生效能上的問題,因為你把顯示還是隱藏的決定權交給元素去判斷,當元素一多,每個元素都要重複判斷。以下是jquery1.3.2的toggle的片段原始碼:

1
2
3
4
this.each(function(){
var state = bool ? fn : jQuery(this).is(':hidden');
jQuery(this)[ state ? "show" : "hide" ]();
}) :

see that?每次都要判斷元素是否被隱藏,然後再決定show or hide。
這也是為何在大量做toggle時效能會差的原因。因此在大量元素的顯示或隱藏時,不要使用toggle來讓元素自己決定要顯示或隱藏。換句話說,當要決定兩個以上元素的顯示或隱藏時,這個「決定」(boolean值)就應該被存起來,而不應該再下一個元素還要再判斷這個決定。