代码中存在同级元素时,nextSibling为何返回null?
问题:为什么
<h1>的nextSibling返回null? 我遇到一个奇怪的问题:页面里每个<h1>后面都紧跟着同级的<p>元素,但调用title.nextSibling时却返回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>
解答
嘿,这个问题我之前也碰到过!核心原因出在你那句document.getElementById('content').innerHTML = '';上——你在遍历<h1>元素之前,就把它们的父容器#content的内容清空了!
你看,document.querySelectorAll('h1')确实能拿到所有的<h1>元素,但这些元素此时还是挂载在DOM树上的。当你执行innerHTML = ''时,浏览器会把#content里的所有子节点(包括那些<h1>和<p>)都从DOM树中移除,并且释放它们之间的关联关系。
等你再遍历这些<h1>的时候,它们已经是“游离”状态的节点了,不再属于原来的DOM结构,自然也就找不到原来的nextSibling(也就是对应的<p>)了,所以返回null。
解决办法
你只需要调整代码顺序,先把需要的节点关系保存好,再清空父容器:
const formIt = () => { const titles = document.querySelectorAll('h1'); // 先把每个h1对应的p元素收集起来,推荐用nextElementSibling避开空白文本节点 const titlePairs = Array.from(titles).map(title => ({ title, p: title.nextElementSibling })); // 再清空内容 document.getElementById('content').innerHTML = ''; // 最后处理并添加到容器中 titlePairs.forEach(({p}) => { let pWrapper = document.createElement('div'); pWrapper.appendChild(p); document.getElementById('content').appendChild(pWrapper); }); }; formIt();
另外补充个小细节:如果你的HTML里<h1>和<p>之间有换行、空格这类空白字符,nextSibling可能会先返回空白文本节点(而不是你想要的<p>元素)。这种情况下,用nextElementSibling可以直接获取下一个元素节点,完美避开文本节点的干扰~
内容的提问来源于stack exchange,提问作者Soroush Bgm
相关产品推荐
相关产品推荐

