You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取嵌套Shadow Root中的活跃元素?document.activeElement失效问题

获取嵌套Shadow Root内部的活跃元素

当页面使用嵌套Shadow DOM时,document.activeElement只能返回最外层的Shadow Root宿主元素,无法直接获取内部实际获得焦点的元素。以下是两种无需为每层Shadow Root添加事件监听器的解决方案:

方法1:利用focus事件的composedPath()属性

当Shadow Root的mode为open时,focus事件会穿透Shadow DOM传播到外部,通过事件对象的composedPath()方法可以获取事件传播的完整路径,路径的第一个元素就是实际获得焦点的内部元素。

修改你的示例代码如下:

window.addEventListener('focus', e => {
  if (e.target instanceof Window) return;
  // 取composedPath的第一个元素作为实际活跃元素
  const actualActiveElement = e.composedPath()[0];
  console.log({ target: e.target, activeElement: document.activeElement, actualActiveElement });
}, true);

对应的HTML结构:

<input placeholder="level 1" />

<div id="div2">
  <template shadowrootmode="open">
    <input placeholder="level 2" />
    <div id="div3">
      <template shadowrootmode="open">
        <input placeholder="level 3" />
        <div id="div4">
          <template shadowrootmode="open">
            <input placeholder="level 4" />
          </template>
        </div>
      </template>
    </div>
  </template>
</div>

方法2:递归遍历Shadow Root获取深层活跃元素

编写一个递归函数,从document.activeElement开始,逐层检查元素的shadowRoot,如果该Shadow Root内部有活跃元素,则继续深入,直到找到最内层的活跃元素:

function getDeepActiveElement(element = document.activeElement) {
  // 如果当前元素有shadowRoot,且内部存在活跃元素
  if (element.shadowRoot && element.shadowRoot.activeElement !== element) {
    return getDeepActiveElement(element.shadowRoot.activeElement);
  }
  return element;
}

// 使用示例:在focus事件中调用
window.addEventListener('focus', e => {
  if (e.target instanceof Window) return;
  const deepActiveElement = getDeepActiveElement();
  console.log({ activeElement: document.activeElement, deepActiveElement });
}, true);

关于事件监听器的疑问

不需要为每层Shadow Root单独添加事件监听器。只要Shadow Root的mode设置为open,外部代码就可以访问其内部的activeElement,或者通过事件的composedPath()获取完整路径。如果是closed模式的Shadow Root,外部无法访问其内部元素,这种情况下确实无法获取内部活跃元素。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:49:58