1

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>
Soroush Bgm
  • 482
  • 2
  • 15
  • It returns null because there isn't a next sibling. Obviously this isn't the case in your example so perhaps there's an h1 elsewhere on the page. – nlta Dec 30 '21 at 00:21
  • @nlta did you try the snippet? There's no other `h1` in the code. This is it. There's three `h1` elements with three `p` elements next to them. So obviously they are siblings. – Soroush Bgm Dec 30 '21 at 00:23
  • 2
    There are no DOM elements left after you use `document.getElementById('content').innerHTML = '';`. – Andy Dec 30 '21 at 00:29

3 Answers3

2

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.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

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.

Kevin Perry
  • 541
  • 3
  • 6
-1

There are two properties to iterate on Nodes or elements:

  1. nextSibling
  2. nextElementSibling

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.firstChild or Node.previousSibling may refer to a whitespace text node rather than the actual element the author intended to get.

[..]

You can use Element.nextElementSibling to obtain the next element skipping any whitespace nodes, other between-element text, or comments. (emphasis mine)

See similar question:

Example

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>
hc_dev
  • 8,389
  • 1
  • 26
  • 38