对于循环DOM基础知识?

时间:2017-10-29 10:48:07

标签: javascript for-loop

let p = document.createElement("p");
let a = document.createElement("a");

for(let i=1; i <= 5; i++) {
    p.textContent = i;      
    a.appendChild(p);
    console.log(a);
}

结果

<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>
<a><p>5</p></a>

我正在努力理解这个基本概念。我知道当我在for循环中移动let p = document.createElement("p");的赋值时,我会得到所需的结果

<a><p>1</p></a>
<a><p>2</p></a>
<a><p>3</p></a>
<a><p>4</p></a>
<a><p>5</p></a>

我肯定认为textContent属性的值会被i覆盖,但是从第一次传递开始,i会立即跳转到5。

我只是想了解这背后的逻辑。谢谢,非常感谢任何帮助。

4 个答案:

答案 0 :(得分:4)

如果将p的声明留在循环之外,那么元素对象只创建一次,而如果将它放在循环中,则每次迭代都会创建一个新对象。

您在第一种情况下看到的原因是p是一个对象,您将一次又一次地附加到a。由于它是同一个对象,因此修改它会随处改变它。

在第二种情况下,您有多个不同的元素对象,您要附加到a。修改一个对其他人没有影响。

编辑:这是因为console.log实际上在循环完成后记录,如Patrick Evans在评论中所述。

另外,您是否注意到a总是有一个元素,即使我们多次调用appendChild

如果你想拥有多个不同的p元素,但是一个p个对象会增加,那么这段代码应该可以工作:

let p = document.createElement("p");
let a = document.createElement("a");

for(let i=1; i <= 5; i++) {
    p.textContent = i;      
    a.appendChild(p.cloneNode(true));
    console.log(a);
}

答案 1 :(得分:2)

这是因为变量p是指向您创建的dom对象的指针。 这不是数据本身!它通过 参考 传递数据。

基本上,当你追加它时,你要附加对象的引用而不是多次复制(克隆)对象。

这就是为什么当您更改对象的值时,引用它的所有位置都会受到影响。

就像你说的那样,为了解决这个问题,只需将let p = document.createElement("p");放入for循环中,或者另外使用p.cloneNode(true),这样就会复制(克隆)你的对象。

答案 2 :(得分:0)

如果我们逐步完成您的代码,最好理解这一点:

let p = document.createElement("p"); // create an element

// loop through this 5 times
for(let i=1; i <= 5; i++) {
    p.textContent = i;      
    a.appendChild(p);
    console.log(a);
}

在第一次迭代i = 1我们将p.textContent设置为1

在第二次迭代i = 2,我们将p.textContent设置为2

但是等等......第一次迭代(p)中使用的i = 1与第二次迭代中的i = 2有何不同(p)?它们没有区别,指的是相同的p.textContent变量。在第二步中,您将覆盖在第一次迭代中设置的p

相反,您应该在循环内创建一个新的p变量,而不是在循环外部。这可确保每个// loop through this 5 times for(let i=1; i <= 5; i++) { let p = document.createElement("p"); // create an element p.textContent = i; a.appendChild(p); console.log(a); } 变量都是唯一的。

请尝试以下方法:

node_modules

答案 3 :(得分:-1)

据我所知,console.log是同步和异步之间的一种灰色区域。显然,您显示的所有控制台日志都显示整个for循环完成后的状态,即使它们被称为中循环。

我们通常可以将console.log视为同步,因为它不会返回任何内容。但它实际上调用的浏览器功能超出了javascript的范围。我想如果你记录的是&#34;简单&#34;足够(字符串,浅层对象等),然后可以立即评估日志显示的内容。

但是如果您正在记录的内容非常复杂(如DOM元素),那么浏览器可能只保存对该对象的引用,然后在浏览器到达时向我们显示日志时对该对象进行解析。在这种情况下,这将在整个for循环完成之后。