纯Javascript:将字符串转换为NodeList

时间:2018-04-11 11:00:00

标签: javascript html5 foreach domparser nodelist

使用纯javascript,我正在尝试将字符串转换为NodeList并将每个NodeListItem附加到容器元素,useinf forEach。

字符串列表有6个项目,但只附加了3个。为什么?

var controlsString = '<button class="{{namespace}}_prev" onclick="isotype_sliders[{{index}}].slide_to(\'prev\');">Slide to prev</button>'+
                '<button class="{{namespace}}_pause" onclick="isotype_sliders[{{index}}].pause(); this.style.display=\'none\'; this.nextElementSibling.style.display=\'initial\';">Pause</button>'+
                '<button class="{{namespace}}_play" style="display: none;" onclick="isotype_sliders[{{index}}].play(); this.style.display=\'none\'; this.previousElementSibling.style.display = \'initial\';">Play</button>'+
                '<button class="{{namespace}}_next" onclick="isotype_sliders[{{index}}].slide_to(\'next\');">Slide to next</button>'+
                '<button class="{{namespace}}_shuffle" onclick="isotype_sliders[{{index}}].shuffle();">Shuffle</button>'+
                '<button class="{{namespace}}_slide_to" onclick="isotype_sliders[{{index}}].slide_to(2);">Slide to 2</button>';
var container = document.getElementById('container');
var getNodes = str => new DOMParser().parseFromString(str, 'text/html').body.childNodes;
var controlsNodes = getNodes(controlsString);
console.log(controlsNodes);
controlsNodes.forEach(function(controlNode, controls_index, listObj){
    console.log(controlNode);
    container.appendChild(controlNode);
});

看看我在JSFiddle上的实验: Help Center

谢谢。

2 个答案:

答案 0 :(得分:4)

关键问题是直接在forEach的结果上使用childNodes。引用Epoch Converter

  

Node.childNodes只读属性会返回实时 NodeList的子级   给定元素的节点[...]

换句话说,每次从controlsNodes追加节点时,都会将它从DOM中的一个位置移动到另一个位置,并重建相应的NodeList - 但是forEach()只是不关心和前进到该NodeList的下一个索引。这就是为什么跳过原始集合的每个偶数元素的原因。

有几种解决方法。最直接的方法是将动态NodeList转换为静态数组 - 使用docsArray.from()

[...controlsNodes].forEach(function(controlNode, controls_index, listObj){
    console.log(controlNode);
    container.appendChild(controlNode);
});

另一种方法是咬紧牙关 - 考虑到NodeList的动态特性:

while (controlsNodes.length !== 0) {
  container.appendChild(controlsNodes[0]);
}

答案 1 :(得分:0)

不确定为什么NodeList无效NodeList,但您可以在将Array.from(controlNodes)转换为Array.prototype.forEach.call(controlsNodes, function (controlNode) {...})var controlsString = '<button class="{{namespace}}_prev" onclick="isotype_sliders[{{index}}].slide_to(\'prev\');">Slide to prev</button>'+ '<button class="{{namespace}}_pause" onclick="isotype_sliders[{{index}}].pause(); this.style.display=\'none\'; this.nextElementSibling.style.display=\'initial\';">Pause</button>'+ '<button class="{{namespace}}_play" style="display: none;" onclick="isotype_sliders[{{index}}].play(); this.style.display=\'none\'; this.previousElementSibling.style.display = \'initial\';">Play</button>'+ '<button class="{{namespace}}_next" onclick="isotype_sliders[{{index}}].slide_to(\'next\');">Slide to next</button>'+ '<button class="{{namespace}}_shuffle" onclick="isotype_sliders[{{index}}].shuffle();">Shuffle</button>'+ '<button class="{{namespace}}_slide_to" onclick="isotype_sliders[{{index}}].slide_to(2);">Slide to 2</button>'; var container = document.getElementById('container'); var getNodes = str => new DOMParser().parseFromString(str, 'text/html').body.childNodes; var controlsNodes = getNodes(controlsString); Array.from(controlsNodes).forEach(function(controlNode, controls_index, listObj){ console.log(controlNode); container.appendChild(controlNode); });时迭代所有元素。

请参阅下面的更正代码。有关更多信息,请参阅https://developer.mozilla.org/en-US/docs/Web/API/NodeList

<div id='container'></div>
{{1}}