【问题标题】:AppendChild in for loop adds every second child?for循环中的AppendChild每隔一个孩子添加一次?
【发布时间】:2021-12-09 03:03:00
【问题描述】:

我需要将子元素包装在 wrap-of-parent 中。在包装之前为父元素和子元素添加一些属性。在下面描述的代码中,如果孩子在单独的一行中位于另一个之下,并且如果它们在一行中,则所有其他孩子都插入到父包裹中。为什么会发生这种情况以及如何解决?

我明白了:

<div id="container">
<div id="parent1">
    <div id="child1"></div>
    <div id="child2"></div>
    <div id="wrap-of-parent1">
        <div id="child3"></div>
        <div id="child4"></div>
    </div>
</div>

我需要得到:

<div id="container">
<div id="parent1">
    <div id="wrap-of-parent1">   
        <div id="child1"></div>
        <div id="child2"></div>
        <div id="child3"></div>
        <div id="child4"></div>
    </div>
</div>

代码:

   var container = document.getElementById("container");
   const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in
 
     for (let parent of parentDivs) {
     // create a new div
     let wrap = document.createElement('div');
     wrap.id = 'wrap-of-' + parent.id;
      // move the parent's children to it
     let children = parent.childNodes;
     
     for (let i = 0; i < children.length; i++) {
     if (children[i].nodeType === Node.ELEMENT_NODE) {
         children[i].setAttribute("data", "somedata");
         wrap.append(children[i]);
     }}
     // and append it to the parent
         parent.appendChild(wrap);
     }
<div id="container">
    <div id="parent1">
        <div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
    </div>
</div>
<! - If the child elements are one below the other in a separate row it works, if they are in one row it does not work ->

【问题讨论】:

  • 一个元素只能在DOM中的一个地方。当您将子元素移入包装器时,它会从 .childNodes 列表中消失,因此当您增加循环索引时,您会跳过一个元素。
  • 您正在改变循环中的数组,它正在改变索引。也许你想先复制收藏:for (const child of [...children])
  • 我刚刚测试过,工作,你能把它作为答案标记为正确答案。
  • CherryDT,我刚刚注意到,即使是空元素也会变得没有子元素,得到一个 -wrap-of- div。我知道这不是主要问题,但你如何解决这个问题?

标签: javascript for-loop wrapper children appendchild


【解决方案1】:

如果您继续移动第一个(索引 0)条目,它将起作用。当遇到错误的 nodeType 时需要添加偏移量以跳过那些,如果没有子节点则不处理该节点:

var container = document.getElementById("container");
const parentDivs = container.querySelectorAll(":scope *"); //if child elements also have child elements, to wrap in

for (let parent of parentDivs) {
    // create a new div
    if (parent.childNodes.length > 0) {
        let wrap = document.createElement('div');
        wrap.id = 'wrap-of-' + parent.id;
        // move the parent's children to it
        let children = parent.childNodes;
        
        const nChildren = children.length;
        let offset = 0;
    
        for (let i = 0; i < nChildren; i++) {
            if (children[offset].nodeType === Node.ELEMENT_NODE) {
                children[offset].setAttribute("data", "somedata");
                wrap.append(children[offset]);
            } else {
                offset++;
            }
        }
        // and append it to the parent
        parent.appendChild(wrap);
    }
}
<div id="container">
    <div id="parent1">
        <div id="child1"></div><div id="child2"></div><div id="child3"></div><div id="child4"></div>
    </div>
</div>

【讨论】:

  • 您好,如果在空元素中发现部分变形,您已设法安排子元素并删除部分变形,您已完成答案。我会请你解释为什么[偏移]? ..,我是 javascript 新手。谢谢
  • @deki0 当遇到不需要的节点 (.nodeType !== Node.ELEMENT_NODE) 时,它们将被抛在后面,因此第一个条目将不再是正确的移动节点。
  • 安德鲁,据我所知,如果父母或孩子是空的,它不会包裹。那么如何插入 parent.innerHTML += parent.id;和孩子 [offset] .innerHTML += children [offset] .id;在 div 换行之前?我知道这不是主要问题,但如果可能的话,它会起到补充作用。
猜你喜欢
  • 2012-09-25
  • 2015-10-13
  • 2021-06-01
  • 1970-01-01
  • 2019-08-13
  • 1970-01-01
  • 1970-01-01
  • 2017-03-14
相关资源
最近更新 更多