简体   繁体   中英

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

I have a variable amount of HTML elements being sent from my backend to my page where I want to then append the elements to the DOM once they are received (rather than all at once) as a kind of status update feature.

However, when I loop through the NodeList of elements received with either a for loop or forEach, appendChild only ever appends the first Node in the list, without iterating past the first loop. Is there a behaviour of this function I'm unaware of that causes this?

Removing the appendChild line has the forEach loop iterating fully, but with it in it only ever iterates once. I have inserted debugging lines that show it stops iterating after the first loop (console.log(i), etc.)

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;
}

I expect all children to be appended within the loop and am confused as to why appendChild only appends the first element in the NodeList

When you append a child to root , it has to be removed from elements , since a node can only be in one place in the DOM at a time. Modifying the NodeList that you're iterating over with forEach() causes it to skip elements, because when you remove something all the indexes shift down.

You should have htmlToElements return an array instead of a NodeList .

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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