分配给变量的 JQuery 对象如何检测变化?

cam*_*dan 4 javascript jquery dom

(首先对不起我的英语)我可以理解将 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.
});
Run Code Online (Sandbox Code Playgroud)

tal*_*myn 5

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

正如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>
Run Code Online (Sandbox Code Playgroud)

如果您针对它运行以下代码:

var $mainGroup = $("#container");
var $subGroup = $mainGroup.find(".similarDivs");
console.log($subGroup);
Run Code Online (Sandbox Code Playgroud)

. . . 你的控制台会显示:Object[div.similarDivs, div.similarDivs, div.similarDivs]

但是,如果您要使用以下代码进行跟进:

$mainGroup.children(":eq(0)").removeClass("similarDivs");
console.log($subGroup);
Run Code Online (Sandbox Code Playgroud)

. . . 你的控制台会显示:Object[div, div.similarDivs, div.similarDivs]

很聪明地看到 1stdiv不再被标记为“similarDivs”类,但还不够聪明地知道,从技术上讲,这意味着它不应再成为$subGroup选择组的一部分。同样,这是因为选择器在单个时间点创建了一堆 jQuery 对象,这些对象指向与选择条件匹配的所有 DOM 元素。

您可以$subGroup通过重新运行选择器来反映其集合中的更改的唯一方法:

$subGroup = $mainGroup.find(".similarDivs");
console.log($subGroup);
Run Code Online (Sandbox Code Playgroud)

. . . 导致: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);
Run Code Online (Sandbox Code Playgroud)

该代码会给你:

HTMLCollection[div.25dd58, div.25dd58, div.25dd58]
HTMLCollection[div.25dd58, div.25dd58]
Run Code Online (Sandbox Code Playgroud)

. . . 无需“重新选择”元素(注意:它还返回 一个HTMLCollection,而不是一个 jQuery Object,这会提示您了解行为的差异)。