如何使用JavaScript选择指定元素之后的第N个特定非子元素
如何使用JavaScript选择指定元素之后的第N个特定非子元素
嘿,这个需求我太熟了!之前做评论抓取类的项目也碰到过,完全不用折腾substring这种字符串处理的方法,用原生JS的DOM API或者CSS选择器就能高效解决,跟querySelector一样顺手!
一、先搞定第一个需求:选择指定元素之后的第一个特定非子元素
就拿你例子里的a元素和它后面的第一个p元素来说,有两种超方便的方法:
方法1:用CSS兄弟选择器+querySelector(最简洁高效)
直接一行代码就能搞定,完美符合你想要的类似querySelector的体验:
const firstPAfterA = document.querySelector('#this_is_the_a_element ~ p:first-of-type');
给你解释下:
#this_is_the_a_element ~ p:选择所有和这个a元素同级、且在它之后的p元素(自动排除a内部的子元素p,完全符合你的要求):first-of-type:从这些符合条件的p元素里挑出第一个,正好就是你要的first_p_after_a
拿到之后你就可以直接操作它,比如打印id:
if (firstPAfterA) console.log(firstPAfterA.id);
方法2:手动遍历(适合需要精细控制的场景)
如果担心兼容性(不过现在主流浏览器都支持上面的选择器),或者需要在遍历过程中加一些额外判断,就用nextElementSibling来逐个找:
const targetA = document.getElementById('this_is_the_a_element'); let currentEl = targetA.nextElementSibling; let firstP = null; while (currentEl) { // 找到第一个p就立刻停止遍历 if (currentEl.tagName === 'P') { firstP = currentEl; break; } // 不是目标元素的话,继续找下一个同级元素 currentEl = currentEl.nextElementSibling; } // 找到后就能用啦 if (firstP) console.log(firstP.id);
二、选择第2、3……第N个特定元素
这里分两种常见场景,我都给你讲明白:
场景1:从指定元素之后开始数,第N个出现的目标元素(忽略中间其他元素)
这应该是你最常用的场景——比如不管中间隔了多少pre、div这类元素,只数出现的p元素,取第2个、第3个。这种情况用遍历计数的方法最靠谱,我给你封装成了一个复用性拉满的函数:
function getNthTargetAfter(startEl, targetTag, n) { let currentEl = startEl.nextElementSibling; let matchCount = 0; // 转成大写避免标签名大小写敏感的坑 const upperTag = targetTag.toUpperCase(); while (currentEl) { if (currentEl.tagName === upperTag) { matchCount++; // 数到第N个就返回这个元素 if (matchCount === n) { return currentEl; } } currentEl = currentEl.nextElementSibling; } // 没找到符合条件的元素就返回null return null; }
用法超级简单:
const targetA = document.getElementById('this_is_the_a_element'); // 取第2个p元素 const secondP = getNthTargetAfter(targetA, 'p', 2); // 取第3个p元素 const thirdP = getNthTargetAfter(targetA, 'p', 3); if (secondP) console.log(secondP.id); // 输出second_p_after_a if (thirdP) console.log(thirdP.id); // 输出third_p_after_a
场景2:指定元素之后的第N个同级元素,且该元素是目标类型
这种场景比较特殊——比如你要找a元素之后的第2个同级元素(不管它是什么),而且这个元素恰好是p。可以用循环跳转nextElementSibling:
const targetA = document.getElementById('this_is_the_a_element'); let targetEl = targetA.nextElementSibling; // 跳转N次,这里以找第2个同级元素为例 const jumpTimes = 2; for (let i = 1; i < jumpTimes; i++) { if (!targetEl) break; // 提前没元素了就终止 targetEl = targetEl.nextElementSibling; } // 最后判断是不是目标类型 if (targetEl && targetEl.tagName === 'P') { console.log(targetEl.id); }
不过这种场景实际用得不多,除非你明确知道DOM结构的固定顺序。
最后碎碎念
为啥不推荐用substring?因为那是在操作HTML字符串,一旦DOM结构有一点点变化(比如多了个空格、换行,或者嵌套结构调整),字符串处理就很容易出错。而直接操作DOM节点的方法是基于元素的实际结构,健壮性和效率都高得多。
备注:内容来源于stack exchange,提问作者Han Han
相关产品推荐
相关产品推荐

