1

我有几个关于 JavaScript 的内部工作原理以及解释器如何处理某些查询的问题

下面的 JQuery 将正确获取 src 中包含单词“flowers”的所有图像

$("img[src*='flowers']");

Jquery 使这非常简单,但纯 javascript 版本是什么?

我们有一个非常大的 DOM。我认为如果这样做$("*[src*='flowers']")会极大地影响性能(通配符元素)。我对 Javascript 解释器在 和 之间的不同之处$("img[src*='flowers']")感兴趣$("*[src*='flowers']")

4

3 回答 3

2

好吧,解释差异的最清晰方法是向您展示如何在纯 JS 中编写两个 DOM 查询:

jQuery的$("img[src*='flowers']")

var images = document.getElementsByTagName('img');//gets all img tags
var result = [];
for (var i = 0; i < images.length;i++)
{
    if (images[i].getAttribute('src').indexOf('flowers') !== -1)
    {//if img src attribute contains flowers:
        result.push(images[i]);
    }
}

如您所见,您只是在搜索所有img元素并检查它们的src属性。如果 src 属性包含子字符串"flowers",则将其添加到result数组中。
$("[src*='flowers']")相当于:

var all = document.getElementsByTagName('*');//gets complete DOM
var result = [];
for (var i =0; i <all.length; i++)
{
    if (all[i].hasAttribute('src') && all[i].getAttribute('src').indexOf('flowers') !== -1)
    {//calls 2 methods, for each element in DOM ~= twice the overhead
        result.push(all[i]);
    }
}

所以节点的总数会比img节点的数量要高很多。除此之外,您正在为所有 img 元素调用两个方法 (hasAttributegetAttibute)(感谢短路评估,所有没有 src 属性的元素,该getAttribute方法不会被调用)有很多为了让您获得相同的结果,幕后会发生更多事情。

注意:
我并不是说这正是jQuery 为您翻译 DOM 查询的方式,它是一个简化版本,但基本原则是不变的。第二个版本(较慢的版本)只处理比第一个更多的元素。这就是为什么它也慢了很多。

于 2013-04-29T23:11:17.247 回答
1

When you use *[src..] you will try to find all elements from the page, but when you use $("img[src..]") the search is restricted to img elements, like this: imgs = document.getElementsByTagName("img")

Heres a JSFiddle getting those images using pure javascript.

Edit:

turn console on so you can see the return from console.log

于 2013-04-29T22:46:55.007 回答
1

直接的 JavaScript 方法是document.querySelectordocument.querySelectorAll。问题在于,并非所有浏览器都支持它们,jQuery(通过 SizzleJS)提供了一种与浏览器兼容的方式来做这些事情。SizzleJS 代表document.querySelectorAll它是否可用,当它不可用时它会依赖其他机制。因此,除非您想自己编写回退代码,否则最好坚持使用SizzleJS之类的东西,它提供了选择器功能而没有 jQuery 的开销。

于 2013-04-29T22:48:58.767 回答