2015-05-29 90 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引用)。但是,也可能有一些差异。 。 。在'