avatar
Published on

Chrome 浏览器移除 Event.path 后的兼容方案

Chrome 浏览器移除 Event.path 后的兼容方案

Chrome 浏览器移除 Event.path 后的兼容方案

问题背景

2023年2月初,Chrome 浏览器(版本 109.0.5414.120)在一次更新中移除了点击等事件中 Event.path 数组参数。值得注意的是:

  • Edge 及其他基于 Chromium 内核的国产浏览器暂未受影响
  • 官方早在 2021 年就已明确 Event.path 属于非标准 API(仅 Chrome 内核单独支持,未被 MDN 标准收录)
  • 相关变更记录可参考 Chromium 官方日志

兼容解决方案

方法1:使用标准 API composedPath()(有限推荐)

MDN 标准中提供了 Event.composedPath() 方法,可返回事件传播路径的数组:

const path = event.composedPath();

注意:部分场景下可能返回空数组(具体原因暂未明确,推测与事件传播阶段或 Shadow DOM 有关)

方法2:手动实现路径收集(推荐)

仿照 composedPath() 原理,通过遍历 DOM 节点的父级链手动构建路径数组,兼容性更可靠:

/**
 * 兼容获取事件传播路径
 * @param e 事件对象
 * @returns 事件传播路径数组(从目标元素到 window)
 */
const getEventPath = (e: Event) => {
  // 优先使用原生支持的方法
  if (e.path && e.path.length) {
    return e.path;
  }
  if (e.composedPath && typeof e.composedPath === 'function') {
    const composedPath = e.composedPath();
    if (composedPath.length) {
      return composedPath;
    }
  }

  // 手动遍历父节点构建路径
  const path: (Node | Window)[] = [];
  let target: Node | null = e.target as Node;
  
  while (target) {
    path.push(target);
    target = target.parentNode;
  }
  
  // 补充文档和窗口对象(模拟原生 path 结构)
  path.push(document, window);
  return path;
};

使用示例

// 为按钮绑定点击事件
document.querySelector('button').addEventListener('click', (e) => {
  // 获取事件路径
  const path = getEventPath(e);
  console.log('事件传播路径:', path);
});

关键说明

  • Event.path 本质是 Chrome 私有属性,移除符合标准规范化趋势,建议尽快替换为兼容方案
  • 手动实现的 getEventPath 方法可完美模拟原生路径结构,支持所有现代浏览器
  • 若项目中大量依赖 Event.path,可通过事件原型链扩展全局兼容:
Event.prototype.getPath = function() {
  // 此处放入上述 getEventPath 方法逻辑
};