通过调用document.getElementsByTagName, document.getElementsByName以及document.getElementsByClassName(部分浏览器不支持),可以返回HTMLCollection对象。表面上,它们与数组很类似,因为它们都包含length属性并且元素都可以通过[index]方式访问。然而,实际上它们并不是数组;诸如push(), slice()与sort()之类的方法不受支持。
考虑下面的HTML文档:
<body>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
<p>Paragraph 3</p>
</body>
我们使用原生JavaScript的getElementsByTagName方法与jQuery选择器分别获取每一个paragraph节点:
var pCollection = document.getElementsByTagName("p");
var pQuery = $("p");
console.log("pCollection.length: ", pCollection.length);
console.log("pQuery.length: ", pQuery.length);
它们都返回了相同的节点,因此集合长度都是3:
pCollection.length: 3 pQuery.length: 3
我们现在再向文档中添加一个paragraph元素,然后再观察一下集合:
// add new paragraph
var newp = document.createElement("p");
newp.appendChild(document.createTextNode("Paragraph 4"));
document.body.appendChild(newp);
//
// display length
console.log("pCollection.length: ", pCollection.length);
console.log("pQuery.length: ", pQuery.length);
运行结果:
pCollection.length: 4 pQuery.length: 3
HTMLCollection对象是实时的(live)。它们会在相应文档发生变化时自动更新。jQuery与其他JavaScript库也使用了诸如document.getElementsByTagName()之类的方法,但是将返回的节点拷贝到一个真正的数组里面。因此,查询得到的结果反映的是文档当时的状态:而不会随着文档的变化自动更新。
两种方法各有利弊。例如,下面的代码会导致无限循环,因为HTMLCollection的长度会在<p>元素增加时自动+1:
var pCollection = document.getElementsByTagName("p");
for (var i = 0; i < pCollection.length; i++) {
document.body.appendChild(pCollection[i].cloneNode(true));
}
有时候,相较于静态的jQuery节点集合或者重复调用选择器,使用速度更快、原生的实时HTMLCollection更合适。幸运的是,我们可以在需要时方便地将任何集合传递给jQuery,例如:
var pCollection = document.getElementsByTagName("p");
// ... add nodes, do work, etc ...
$(pCollection).addClass("myclass");
jQuery与其他库可以减少开发工作量,但是,在可能的情况下,使用原生(plain old)JavaScript,可以避免额外的文件请求与处理开销,从而写出更加高效的代码。
原文链接:http://www.sitepoint.com/javascript-vs-jquery-html-collections/
本文链接:http://bookshadow.com/weblog/2015/10/17/javascript-vs-jquery-html-collections/
请尊重作者的劳动成果,转载请注明出处!书影博客保留对文章的所有权利。