繁体   English   中英

appendChild 不会 append 相同的元素两次

[英]appendChild doesn't append the same element twice

我有一个valuesArray和一个transcribedPoems诗 arrays。 如果它们两个中都存在一个键,我想在TranscribedAll子组中为我的select元素添加一个option 如果没有,那么我希望该选项仅在All子组中可用。 这是我的代码:

let valuesArray = [   
    ["1", "a manuscript"], ["2", "another one"]
]

const transcribedPoems =['2']

let optGroupTranscribed = document.createElement("optgroup");
optGroupTranscribed.setAttribute("label", "Transcribed")

let optGroupAll = document.createElement("optgroup");
optGroupAll.setAttribute("label", "All")

let select = document.createElement("select");

valuesArray.forEach(function(element) {
        
        let option = document.createElement("option");
        option.value = element[0];
        option.text = element[1];
        
        if (transcribedPoems.includes(element[0])) {

            optGroupTranscribed.appendChild(option);
            optGroupAll.appendChild(option);
            
        }  else {
        
            optGroupAll.appendChild(option);
        }
        
    });

select.appendChild(optGroupTranscribed);
select.appendChild(optGroupAll);
    
document.getElementById("manifests").appendChild(select);

上面的代码对optGroupTranscribed没有任何作用。 我注意到如果我选择optGroupAll.appendChild(option); 从条件中出来,那么我确实在transcribed子组中有转录的诗歌(而不是在All one 中)。 不过,我希望转录的诗歌也包含在All子组中。 我错过了什么?

我得到什么:

<select>
  <optgroup label="Transcribed">
    <option value="2">another one</option>
  </optgroup>
  <optgroup label="All">    
    <option value="1">a manuscript</option>
  </optgroup>
</select>

预期结果:

<select>
  <optgroup label="Transcribed">
    <option value="2">another one</option>
  </optgroup>
  <optgroup label="All">    
    <option value="1">a manuscript</option>
    <option value="2">another one</option>
  </optgroup>
</select>

forEach循环的一次迭代中,您只创建一个option元素,因此您不能期望有两个作为结果。

appendChild的第二次调用实际上option移到那里,将其从第一个选项组中取出。

您可以调用option.cloneNode(true)来解决这个问题。

这里有一个有趣的微妙之处。 当您使用createElement时,它会创建一个 HTMLElement 实例(用于子类option )。 当您将该元素appendChild到另一个元素时,它会被放置在该元素的 DOM 树中。

如果您将 go 放置在另一个元素的 DOM 树中,它将使整个树(包含optGroupTranscribedoptGroupAll的树)不是树,因为两个元素共享一个子option

相反,您可以调用option.cloneNode()来制作元素的副本。 因此,尝试将其更改为:

optGroupTranscribed.appendChild(option.cloneNode());

这样做...

 const newDomElm = tag => document.createElement(tag), transcribedPoems = ['2'], valuesArray = [ ['1', 'a manuscript'], ['2', 'another one' ] ], mySelect = document.querySelector('#manifests').appendChild(newDomElm('select')); let optGroupTranscribed = mySelect.appendChild(newDomElm('optgroup')), optGroupAll = mySelect.appendChild(newDomElm('optgroup')); optGroupTranscribed.label = 'Transcribed' optGroupAll.label = 'All' valuesArray.forEach(([val,lib]) => { if ( transcribedPoems.includes(val)) optGroupTranscribed.appendChild( new Option(lib,val) ) optGroupAll.appendChild( new Option(lib,val) ) })
 <div id="manifests"></div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM