2015-05-29 66 views
1

(首先感謝我的英語)我可以理解,將JQuery選擇器找到的JQuery對象分配給一個變量,每次使用JQuery選擇器都會有更好的性能。我無法理解的部分是JQuery如何檢測不受JQuery操作的更改?這裏是一個例子:分配給變量的JQuery對象如何檢測變化?

<div id="divState">First State</div> 

$(document).ready(function() { 
    var testElement = $("#divState"); 
    alert(testElement.text());//alerts "First State". 
    document.getElementById("divState").innerHTML = "Second State";//Div has changed outside of the JQuery object. 
    alert(testElement.text());//alerts "Second State"??? How a variable detects changes. 
}); 
+1

那不是一個變化檢測,它只是讀取底層DOM元素上的innerHTML,innerText,textContent屬性。 –

回答

2

嗯,它知道,但它不知道。 。 。

As Blazemonger指出,當你創建一個jQuery對象時,對象中的其中一個項目本質上只是一個指向頁面中實際DOM元素的指針。所以,就像你在你的例子中展示的那樣,每當你檢查那個對象的屬性時,它都會檢查這個元素並向你展示他們目前的任何東西。如果它們在兩次檢查之間發生變化,您將看到不同之處。

但是,jQuery不是100%智能的。 。 。如果你想改變選擇器的某些東西,那麼知道更新對象集合而不重新選擇它們是不夠智能的。例如,看看這個HTML:

<div id="container"> 
    <div class="similarDivs">Div 1</div> 
    <div class="similarDivs">Div 2</div> 
    <div class="similarDivs">Div 3</div> 
</div> 

如果你對它運行下面的代碼:

var $mainGroup = $("#container"); 
var $subGroup = $mainGroup.find(".similarDivs"); 
console.log($subGroup); 

。 。 。控制檯會顯示:Object[div.similarDivs, div.similarDivs, div.similarDivs]

但是,如果你要遵循了這個代碼:

$mainGroup.children(":eq(0)").removeClass("similarDivs"); 
console.log($subGroup); 

。 。 。您的控制檯會顯示:Object[div, div.similarDivs, div.similarDivs]

它足夠聰明地看到第一個div不再標記「similarDivs」類,但它在技術上不夠聰明,從技術上講,這意味着它不應該再成爲$subGroup選擇組的一部分。同樣,這是因爲選擇器創建了一堆jQuery對象,這些對象指向與選擇標準在單個時間點匹配的所有DOM元素。

,你可以得到$subGroup以反映其集合中的變化的唯一途徑是通過重新運行選擇:

$subGroup = $mainGroup.find(".similarDivs"); 
console.log($subGroup); 

。 。 。導致:Object[div.similarDivs, div.similarDivs]


其中一個最大的原因,這是非常重要的(除了知道,當你使用選擇:)),是因爲JavaScript並行爲是那樣的。 。 。如果你寫一個類似的功能集於JS,你會得到不同的結果:

var mainGroup = document.getElementById("container"); 
var subGroup = mainGroup.getElementsByClassName("similarDivs"); 
console.log(subGroup); 
mainGroup.children[1].className = ""; 
console.log(subGroup); 

該代碼就會給你:

HTMLCollection[div.25dd58, div.25dd58, div.25dd58] 
HTMLCollection[div.25dd58, div.25dd58] 

。 。 。而不需要「重新選擇」元素(注:它也返回HTMLCollection,而不是一個jQuery Object,它提示您行爲的差異)。

+0

感謝您的解釋。到目前爲止,我從評論中瞭解到的是;正如@Blazemonger指出的那樣;返回對象保存DOM元素的指針而不是屬性值等。所以當我需要一個元素屬性的值時,它會跟隨DOM對象的指針並獲取它。 – camadan

+0

或多或少,是的。 jQuery提供的「幕後」方法是做這件事的捷徑,但是,如果需要,你也可以自己做。你實際上可以使用'[0]'從一個jQuery對象訪問DOM對象,讓你訪問原生的JS DOM方法。所以,如果你正在尋找文本輸入的值,你可以使用'$ someJqueryObject [0] .value'(JS引用)或$ someJqueryObject.val()'(jQuery引用)。但是,也可能有一些差異。 。 。在'