jQuery中的選擇器:visible對visibility:hidden的處理

首先先介紹visibility這個CSS屬性。

  visibility用於表示該元素是否顯示,其取值有:

  1.   visible:設置對象可視。
  2.   hidden:設置對象隱藏。
  3.   collapse:主要用來隱藏表格的行或列,隱藏的行或列能夠被其他內容是用。

  這裏需要說明的是,collapse在IE6及更早的瀏覽器不支持,它的作用只在表格中生效,對於其他的對象,等同於display:hidden。

  介紹到這裏,也許我們會有個疑問,那就是visibility:hidden與display:none有什麼區別呢?他們的不同之處就是隱藏的對象是否佔據位置。visibility:hidden在對象隱藏之後,它所佔據的地方並不被其他元素佔據。就好比一個人穿着隱身衣一樣,雖然我們看不見他,但是他實際還在那裏,我們仍然能摸到他,他所站的位置也不能放別的東西。但是,display:none就真的消失了,這個人就真的不存在了。因此,如果我們需要將一個容器隱藏,但是又不想讓它後面的內容佔據他的位置,那麼visibility:hidden就派上用場了。(其實關於visibility:hidden與display:none的區別在於,前者在瀏覽器解析完DOM樹之後,將這個容器放入渲染樹進行計算和顯示。而後者在生成DOM樹,不會放到渲染樹中進行計算和繪圖)

  那麼現在就有一個問題,就是如果一個元素是通過visibility:hidden隱藏了,那麼我們如何通過jquery的選擇器選擇到它呢?我們顯而易見的會想到:visible。這個語法是選擇到可見的元素,再通過取反就可以了,因此,下面的代碼可能是你想到的最簡單的例子:

複製代碼
<script type="text/javascript">
$(function(){
    alert($('div:not(:visible)').length);
});
</script>
<body>
<div id="a" style="width:100px; height:100px; visibility:hidden;">11</div>
</body>
複製代碼

但是實際上,alert的結果是:0,也就是說,查找不可見的div沒有找到。爲什麼會是這樣呢?其實,原因是jQuery判斷visible的邏輯和我們想象中的邏輯不同,我們認爲這個不可見是眼睛看不到的。而jQuery的邏輯不是這樣的,jquery的判斷邏輯是:這個對象的offsetWidth和offsetHeight都爲0纔是不可見。而visibility:hidden的對象元素這兩個值都是不爲0的。從這看來,選擇器這樣寫,是無法選擇到這個div的。(其實這個理解起來也不難,雖然裏面的內容看不到了,但是它還在這裏啊,還佔據着位置啊,所以必然不是不可見的)

  在jQuery的早些版本(1.3之前),上述代碼是可以選擇到這個div的,因爲那個時候,visible的邏輯和我們想的一樣,即:除了display:none和visibility:hidden之外,其他都爲true。它之所以做了這個修改,很大的原因是效率問題。我們可以在官方的doc上找到原文:

  • In jQuery 1.3.1 (and older) an element was visible if its CSS "display" was not "none", its CSS "visibility" was not "hidden", and its type (if it was an input) was not "hidden".
  • In jQuery 1.3.2 an element is visible if its browser-reported offsetWidth or offsetHeight is greater than 0.

詳情可以參考全文:http://docs.jquery.com/Release:jQuery_1.3.2#:visible.2F:hidden_Overhauled

  根據上面的原理,我們其實可以做一個小小的修改,如果我們把div的樣式改成:width:0; height:0;去掉visibility:hidden,我們刷新下看看,alert彈出了1,也就是說,它仍然能找到這個div,與display:none與visibility:hidden無關了,而且div中的“11”還顯示在頁面上呢,但是,jquery認爲它是不可見的。

  說了這麼多,那麼解決辦法呢,既然visible的判斷的邏輯已經和我們想象的有偏差,那麼我們可以通過重新將老版本的jquery邏輯添加進來。方法有很多,我這裏給出一個用filter方法實現的代碼:

$('div').filter(function(){
   return ($(this).css('visibility') == 'hidden' || $(this).css('display') == 'none');
});

上面的代碼就可以實現visibility:hidden的選擇了。當然,如果我們常用這個方法的話,可以把它封裝一下。


原文地址:http://www.cnblogs.com/echoloyuk/archive/2013/03/20/2971440.html

發佈了74 篇原創文章 · 獲贊 43 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章