NodeList.forEach 中的 appendChild 仅附加来自 readableStream 的第一个元素

appendChild in NodeList.forEach only appends the first element from readableStream

我有可变数量的 HTML 元素从我的后端发送到我的页面,然后我想在收到这些元素后将它们附加到 DOM (而不是一次全部) 作为一种状态更新功能。

但是,当我遍历使用 for 循环或 forEach 接收到的元素的 NodeList 时,appendChild 只会追加列表中的第一个节点,而不会遍历第一个循环。是否有我不知道的此函数的行为导致了此问题?

删除 appendChild 行会使 forEach 循环完全迭代,但其中只迭代一次。我插入了调试行,显示它在第一个循环后停止迭代(console.log(i) 等)

fetch(`http://localhost:8081/${focussed.textContent}`)
            .then(res => {
                var reader = res.body.getReader();
                function read() {
                    return reader.read().then(({value, done}) => {
                        if (done) {
                            console.log('done');
                            return;
                        }

                        let string = new TextDecoder("utf-8").decode(value);
                        let elements = htmlToElements(string);

                        let root = document.getElementById("root");

                        elements.forEach(child => {
                            root.appendChild(child);
                        })


                        read();
                    });
                };
                read();
            })
            .catch((err) => {
                console.log(err);
            });
    }
}, false);

function htmlToElements(html) {
    let template = document.createElement('template');
    template.innerHTML = html;
    return template.content.childNodes;
}

我希望所有子元素都附加到循环中,但我很困惑为什么 appendChild 只附加 NodeList 中的第一个元素

当您将子级附加到 root 时,必须将其从 elements 中删除,因为节点一次只能位于 DOM 中的一个位置。修改您正在使用 forEach() 迭代的 NodeList 会导致它跳过元素,因为当您删除某些内容时,所有索引都会向下移动。

你应该 htmlToElements return 一个数组而不是 NodeList

function htmlToElements(html) {
    let template = document.createElement('template');
    template.innerHTML = html;
    return Array.from(template.content.childNodes);
}