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

时间:2015-01-22 19:54:29

标签: javascript selectors-api

我已经在9个月左右抛弃了jquery并且需要一个选择器引擎(没有麻烦,不介意即< 7支持)所以我通过创建这个函数创建了document.querySelectorAll的简化版本:

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

这种方法在95%的情况下完全没问题,但我现在已经有这个问题一段时间了,我已经研究过mdn,w3c,SO而不是忘记Google :)但是还没有找到答案为什么我只获得了所请求类的第一个元素。 而且我知道只返回的第一个元素是由最后的“[0]”引起的,但是如果我删除它就不能使用该函数所以我试图用一个索引变量来增加一个for循环取决于具有该类的元素的长度,如下所示:

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感到非常沮丧...... 但是我顽固的内在自我继续前进,我继续失败(分层循环)所以我知道现在真的是时候提出这些问题了:

为什么它只返回该类的第一个元素而不是全部?

为什么我的for循环失败?

为什么我的while循环失败?

谢谢你,因为非常感谢任何/所有帮助。

3 个答案:

答案 0 :(得分:4)

  

为什么它只返回该类的第一个元素而不是全部?

因为您明确地从结果中获取第一个元素并返回该结果。

  

为什么我的for循环失败?

因为每次循环结束时都会用新值覆盖result。然后你回到最后得到的东西。

  

为什么我的while循环失败?

同样的原因。


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

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";
}

答案 1 :(得分:3)

您将返回单个元素。你可以返回数组。如果您希望能够一次性对所有元素执行jQuery样式,则可以将回调传递给您的函数;

&#13;
&#13;
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';
    });
});
&#13;
<p>One</p>
<p>Two</p>
<p>Three</p>

<button class='change-all'>Change Paragraphs</button>
<button class='change-second'>Change Second Paragraph</button>
&#13;
&#13;
&#13;

然后你可以调用使用回调

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

或者您可以使用返回的数组

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

答案 2 :(得分:1)

此循环

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
}