You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

jQuery .has()方法及特定选择器的原生JavaScript等效实现问询

这两个问题问得很到位,咱们逐个来解决:

1. 有没有和jQuery .has()等效的原生JavaScript实现?

原生JS里并没有和jQuery .has()完全一一对应的方法,但现在有两种非常实用的替代方案:

方案一:用CSS :has()伪类(推荐,现代浏览器)

现在主流浏览器(Chrome、Firefox 121+、Safari 15.4+)都已经支持CSS的:has()伪类,它的作用就是筛选包含指定子元素的父元素,用法和jQuery .has()几乎一致。举个例子:

  • jQuery写法:$('.analytics').has('a')
  • 原生写法:document.querySelectorAll('.analytics:has(a)')

方案二:手动遍历过滤(兼容旧浏览器)

如果需要兼容一些老旧浏览器,可以先获取目标元素集合,再通过querySelector()检查是否存在子元素来过滤:

// 先拿到所有.analytics元素
const analyticsElements = document.querySelectorAll('.analytics');
// 过滤出包含<a>标签的元素
const filteredElements = Array.from(analyticsElements).filter(el => el.querySelector('a') !== null);

另外也可以用Node.contains()方法,但需要先拿到子元素再反向找父元素,适合特定场景:

const allLinksInAnalytics = document.querySelectorAll('.analytics a');
// 用Set去重,避免同一个.analytics被多次选中
const filteredElements = [...new Set(allLinksInAnalytics.map(link => link.closest('.analytics')))];

2. 目标选择器的原生最优实现

你的需求是:在.main-container内,选取所有id不为"promo"且包含<a>标签的.analytics元素。最优实现分两种情况:

优先推荐:组合使用CSS选择器(简洁高效)

在现代浏览器环境下,直接用:not():has()组合的原生选择器就能一步到位,完全匹配你的需求:

const targetElements = document.querySelectorAll('.main-container .analytics:not(#promo):has(a)');

这个选择器的逻辑拆解:

  • .main-container .analytics:定位到.main-container下所有的.analytics子元素
  • :not(#promo):排除掉id为promo的元素
  • :has(a):只保留内部包含<a>标签的元素

兼容旧浏览器的方案

如果必须支持不兼容:has()的浏览器,可以先拿到初步筛选的元素,再过滤掉不包含<a>的:

// 先获取id不为promo的.analytics元素
const candidateElements = document.querySelectorAll('.main-container .analytics:not(#promo)');
// 过滤出包含<a>标签的元素
const targetElements = Array.from(candidateElements).filter(el => el.querySelector('a') !== null);

这种写法和你已经尝试的代码很接近,只多了一步过滤操作,逻辑清晰,兼容性拉满。

内容的提问来源于stack exchange,提问作者asw1984

火山引擎 最新活动