如何获取父级accordion类div的可聚焦元素并排除嵌套同类元素
如何获取父级Accordion中的可聚焦元素并跳过嵌套Accordion内的元素
需求:获取class为accordion的div中的可聚焦元素(a和button),但跳过嵌套的同class div内的元素。当前代码会选中所有button和a元素,预期仅获取父级accordion下的链接和按钮。
HTML结构
<div class="accordion"> <div class="accordion-content"> <a href="#">link</a> <button>button</button> <div class="accordion"> <div class="accordion-content"> <button>button inside nested accordion</button> </div> </div> </div> </div>
当前JS代码(存在问题)
const accordionElement = document.getElementsByClassName("accordion")[0]; const accordionContent = accordionElement.getElementsByClassName("accordion-content")[0]; const accordionFocusableElements = accordionContent.querySelectorAll("div:not(.accordion) a, div:not(.accordion) button");
问题原因
原选择器div:not(.accordion) a, div:not(.accordion) button逻辑有漏洞:嵌套按钮的父元素是.accordion-content(不属于.accordion类),因此该按钮会被错误匹配。
解决方案
方案1:使用:scope伪类限定选择范围
:scope代表当前上下文元素(即accordionContent),通过它精准限定查找范围,同时排除嵌套.accordion元素下的目标:
const accordionElement = document.getElementsByClassName("accordion")[0]; const accordionContent = accordionElement.getElementsByClassName("accordion-content")[0]; const accordionFocusableElements = accordionContent.querySelectorAll( ":scope > a, :scope > button, :scope > *:not(.accordion) a, :scope > *:not(.accordion) button" );
方案2:先全选再过滤
先选中所有目标元素,再通过closest()找到最近的.accordion父元素,判断是否为最外层accordion,过滤掉嵌套内的元素:
const accordionElement = document.getElementsByClassName("accordion")[0]; const accordionContent = accordionElement.getElementsByClassName("accordion-content")[0]; const allFocusable = accordionContent.querySelectorAll("a, button"); const accordionFocusableElements = Array.from(allFocusable).filter(el => { return el.closest(".accordion") === accordionElement; });
两种方案均可得到预期结果:[a, button]
内容的提问来源于stack exchange,提问作者Shakeam
相关产品推荐
相关产品推荐

