为什么在循环中使用 $('ul li').html 的工作方式与普通 javascript 中的等效工作方式不同?

Why does using $('ul li').html inside a loop work differently from it's equivalent in vanilla javascript?

提问人:brebz7 提问时间:4/28/2019 最后编辑:brebz7 更新时间:4/28/2019 访问量:27

问:

我不明白为什么 $('selector').html() 在循环中使用时与 document.querySelectorAll 的工作方式不同。我之所以问这个问题,是因为我相信答案可能会让我更好地理解闭包。

假设我有一个 HTML 文件,其中包含一个包含 3 个空列表项的无序列表。

<ul>
 <li></li>
 <li></li>
 <li></li>
</ul>

接下来,我想使用升序循环和 jQuery 在列表项中插入一些值,如下所示:

$(document).ready(function () {
  for (let i = 0; i < 3; i++) {
    $('ul li').html(i); /// Output: all list items are filled with 2
  }
})

所有列表项现在都包含“2”,这不是我所期望的。我期待 0、1、2。

接下来,我也在JS中尝试了同样的事情,但输出不同

window.onload = function () {
  let list = document.querySelectorAll('ul li');

  for (let i = 0; i < 3; i++){
    list[i].innerHTML = i; //Output: 0 1 2
  }
}

为了在我的代码上找到 jQuery 版本的修复程序,我检查了关于闭包的 MDN 部分,并找到了以下修复程序:

$(document).ready(function () {
  for (let i = 0; i < 3; i++) {
    $('ul li').html(foo(i)); /// output: 0 1 2
  }

  function foo(n) {
    return function bar(n) {
      return n;
    }
  }
})

即使目前有效,我想知道为什么使用 $().html() 的工作方式与普通 JS 示例不同?

JavaScript jQuery 闭包

评论

0赞 u_mulder 4/28/2019
$('ul li')返回适合选择器的所有项。
0赞 KB_ 4/28/2019
$('selector').正在选择每个可能的元素,当循环结束时,它是 2 在每个<li>
0赞 brebz7 4/28/2019
为什么我在标题中输入“选择器”,我通常指的是任何选择器。确切的选择器无关紧要。

答:

0赞 CertainPerformance 4/28/2019 #1

问题在于,使用 ,您总是选择所有 s 并设置所有 s 的 HTML。在第一次迭代中,将所有 s 设置为 。在第二次迭代中,您将所有元素都设置为 1。到最后,它们都是 2。您需要改为循环访问集合:$('ul li').html(ul liul liinnerHTML0innerHTMLinnerHTML$('ul li')

const lis = $('ul li');
for (let i = 0; i < lis.length; i++) {
  $(lis[i]).html(i); /// output: 0 1 2
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

使用函数进行调用时,jQuery 使用要迭代的当前元素的索引调用该函数,并将返回值分配给该元素的 innerHTML。.html

for (let i = 0; i < 3; i++) {
  $('ul li').html(foo(i)); /// output: 0 1 2
}

function foo(n) {
  return function bar(n) {
    return n;
  }
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li></li>
  <li></li>
  <li></li>
</ul>

0赞 u_mulder 4/28/2019 #2

$('ul li').html(i);选择适合选择器的所有项目(在您的情况下为 - 全部),并将其 HTML 设置为 。在第一次迭代时,html 设置为 ,然后是 ,最后是 。lii012

等同于:

for (let i = 0; i < 3; i++){
    list[i].innerHTML = i; //Output: 0 1 2
}

for (let i = 0; i < 3; i++) {
    $('ul li').eq(i).html(i);
}