In this part of code, why nextSibling returns null ?
const formIt = () => {
const titles = document.querySelectorAll('h1');
document.getElementById('content').innerHTML = '';
titles.forEach(title => {
console.log(title.nextSibling);
let p = title.nextSibling; //Returns null
let pWrapper = document.createElement('div');
pWrapper.appendChild(p);
document.getElementById('content').appendChild(pWrapper);
});
};
formIt();
<div id='content'>
<h1>...</h1>
<p>...</p>
<h1>...</h1>
<p>...</p>
<h1>...</h1>
<p>...</p>
</div>
On line 3 you set the innerHTML of content to an empty string.
That removes all the h1 and p elements from the DOM.
They aren’t siblings after that.
——
Fiddle with innerHTML after you have finished the loop.
Simply because, by the time the forEach() runs, you've removed all those objects from the DOM:
document.getElementById('content').innerHTML = '';
...so they no longer have any siblings.
There are two properties to iterate on Nodes or elements:
See the note at documentation of nextSibling:
Note: Browsers insert Text nodes into a document to represent whitespace in the source markup. Therefore a node obtained, for example, using
Node.firstChildorNode.previousSiblingmay refer to a whitespace text node rather than the actual element the author intended to get.[..]
You can use
Element.nextElementSiblingto obtain the next element skipping any whitespace nodes, other between-element text, or comments. (emphasis mine)
See similar question:
const headings = document.querySelectorAll('h1');
console.log("headings (count):", headings.length);
let firstHeading = headings[0];
console.log("first h1 nextSibling (data):", firstHeading.nextSibling.data);
console.log("first h1 nextElementSibling (data):", firstHeading.nextElementSibling.data);
let secondHeading = headings[1];
console.log("second h1 nextSibling (data):", secondHeading.nextSibling.data);
console.log("second h1 nextElementSibling (data):", secondHeading.nextElementSibling.data);
<div id='content'>
<h1>heading_1</h1>text_1
<p>paragraph_1</p>
<h1>heading_2</h1>
<p>paragraph_2</p>
</div>