首页 > 解决方案 > 多次附加jQuery元素

问题描述

对于 html:

<body>
  <p>Para 1</p>
  <p>Para 2</p>
  <p>Para 3</p>
  <p>Para 4</p>
  <p>Para 5</p>
</body>

如果我们在脚本中使用以下代码

$(function() {
  let a = $('<span> span 1 </span>');
  $('p').append(a);

  let temp = $('span');
  for(i = 0; i < temp.length; i++) {
    console.log(temp.eq(i) === a);
  }
});

    $(function() {
      let a = $('<span> span 1 </span>');
      $('p').append(a);
    
      let temp = $('span');
      for(i = 0; i < temp.length; i++) {
        console.log(temp.eq(i) === a);
      }
    });
p { border: 1px solid green; }
span { border: 1px solid blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
      <p>Para 1</p>
      <p>Para 2</p>
      <p>Para 3</p>
      <p>Para 4</p>
      <p>Para 5</p>
    </body>

我希望结果为真,因为相同的元素附加到所有<p>元素。有人可以解释为什么结果是错误的吗?

标签: jquery

解决方案


首先,它总是错误的,因为

var a = $("<span>span 1</span>")

在内存中创建一个jquery 对象,没有相应的 DOM 节点。

当您附加此内容时,$('p').append(a)您会附加多个副本,原始 (in var a) 仍在内存中。

因此,当您获取新实例时,temp = $('span')您是从 DOM 中获取它们的。

还要注意,===在对象上检查它们是否是同一个实例,并且还要注意$(selector)查询不是实时查询——它们只得到当时存在的内容。所以它们永远不会是同一个a.length == 1对象$("span").length == 5

其次,你不能比较两个 jquery 对象,===因为它们不是一个对象的同一个实例,这是你的测试的一个更简洁的版本:

console.log($("div") === $("div"))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>div 1</div>


您可以更新您的 js 以仅查看 DOM 节点

console.log(temp[i] === a[i]);

这仍然是错误的,就像a在记忆中一样

$(function() {
  let a = $('<span> span 1 </span>');
  $('p').append(a);

  let temp = $('span');
  for (i = 0; i < temp.length; i++) {
    console.log(temp[i] === a[i]);
  }
});
p { border: 1px solid green; }

span { border: 1px solid blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <p>Para 1</p>
  <p>Para 2</p>
  <p>Para 3</p>
  <p>Para 4</p>
  <p>Para 5</p>
</body>

将其转换为与之前相同以仅查看 DOM 节点(不包括内存问题),您现在可以看到比较节点确实返回true.

// derived example
console.log($("div")[0] === $("div")[0])
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>div 1</div>

但是与现有项目进行比较将是错误的,因为您已将 1 个项目变为 5 个。所以($("span")[0] === $("span")[1]) === false


一份文件附录。如果您比较 HTML(字符串)而不是对象,那么是的,它们都是相同的

$(function() {
  let a = $('<span> span 1 </span>');
  $('p').append(a);

  let temp = $('span');
  for (i = 0; i < temp.length; i++) {
    console.log(temp.eq(i).html() === a.html());
  }
});
p { border: 1px solid green; }
span { border: 1px solid blue; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<body>
  <p>Para 1</p>
  <p>Para 2</p>
  <p>Para 3</p>
  <p>Para 4</p>
  <p>Para 5</p>
</body>


推荐阅读