使用 querySelectorAll 获取具有该 class 名称的所有元素,而不仅仅是第一个

Using querySelectorAll to get ALL elements with that class name, not only the first

我在大约 9(ish) 个月前放弃了 jquery 并且需要一个选择器引擎(没有所有的麻烦并且不介意 ie<7 支持)所以我做了一个简化版本的 document.querySelectorAll 通过创建这个函数:

// "qsa" stands for: "querySelectorAll"
window.qsa = function (el) {
  var result = document.querySelectorAll(el)[0];
  return result;
};

这在 95% 的时间里工作得很好,但我遇到这个问题已经有一段时间了,我已经研究了 mdn、w3c、SO,别忘了 Google :) 但还没有找到了关于为什么我只得到带有请求的 class 的第一个元素的答案。 而且我知道只有返回的第一个元素是由末尾的“[0]”引起的,但是如果我删除它该函数将不起作用所以我试图用一个增加的索引变量制作一个for循环值取决于具有 class 的元素的长度,如下所示:

window.qsa = function (el) {
  var result, el = document.querySelectorAll(el);
  for(var i = 0; i < el.length; ++i) {
   result = el[i];
  }
  return result;
};

同样没有用,所以我尝试了这样的 while 循环:

window.qsa = function (el) {
  var result, i = 0, el = document.querySelectorAll(el);
  while(i < el.length) {
    i++;
  }
  result = el[i];
  return result;
};

现在我开始怀疑是否有任何效果?我对 document.querySelectorAll 感到非常沮丧... 但是我顽固的内心一直在前进,我一直在失败(分层循环)所以我知道现在真的是时候问这些问题了:

为什么它只返回带有 class 的第一个元素而不是所有元素?

为什么我的 for 循环会失败?

为什么我的 while 循环会失败?

非常感谢您的帮助。

Why is it only returning the first element with that class and not all of them?

因为您明确地从结果中获取了第一个元素 return 那。

Why does my for loop fail?

因为每次循环结束时都会用新值覆盖 result。然后你 return 你得到的最后一件事。

Why does my while loop fail?

同样的道理。


如果你想要所有元素,那么你只需得到 运行 函数的结果:

return document.querySelectorAll(el)

这将为您提供一个包含所有元素的 NodeList 对象。


既然你说的是你想要的,我将推测你真正的问题是什么(即为什么你认为它不起作用)。

您没有向我们展示您如何处理 运行 该函数的结果,但我的猜测是您正试图将其视为一个元素。

它不是一个元素。它是一个NodeList,就像一个数组。

例如,如果您想更改元素的背景颜色,您可以这样做:

element.style.backgroundColor = "red";

如果要更改 NodeList 中每个元素的背景颜色,则必须依次更改 每个 的背景颜色:使用循环。

for (var i = 0; i < node_list.length; i++) {
    var element = node_list[i];
    element.style.backgroundColor = "red";
}

这个循环

for(var i = 0; i < el.length; ++i) {
 result = el[i];
}

每次都会覆盖您的结果变量。这就是为什么你总是只得到一个元素。

不过,您可以在外部使用结果,并对其进行迭代。有点喜欢

var result = window.qsa(el)
for(var i = 0; i < result.length; ++i) {
  var workOn = result[i];
  // Do something with workOn
}

您正在 return单一元素。您可以 return 数组。如果您希望能够一次对所有元素进行操作,jQuery 样式,您可以将回调传递到您的函数中;

window.qsa = function(query, callback) {
    var els = document.querySelectorAll(query);
    if (typeof callback == 'function') {
        for (var i = 0; i < els.length; ++i) {
            callback.call(els[i], els[i], i);
        }
    }
    return els;
};


qsa('button.change-all', function(btn) {
    // You can reference the element using the first parameter
    btn.addEventListener('click', function(){
        qsa('p', function(p, index){
            // Or you can reference the element using `this`
            this.innerHTML = 'Changed ' + index;
        });
    });
});

qsa('button.change-second', function(btn) {
    btn.addEventListener('click', function(){
        var second = qsa('p')[1];
        second.innerHTML = 'Changed just the second one';
    });
});
<p>One</p>
<p>Two</p>
<p>Three</p>

<button class='change-all'>Change Paragraphs</button>
<button class='change-second'>Change Second Paragraph</button>

然后你可以使用回调

qsa('P', function(){
    this.innerHTML = 'test';
});

或者您可以使用 returned

的数组
var pList = qsa('p');
var p1 = pList[0];