FireFox火狐浏览器Event.path属性不存在

722 阅读1分钟

场景:

在做组件拖拽过程中,需要获取到触发元素冒泡过程中的所有元素,所以使用了event.path属性。在Chrome下正常运行,但是在FireFox下测试时发现,完犊子,失效了,通过问题排查,发现了Chrome下打印的event事件对象FireFox下打印的事件对象不一样,在火狐浏览器下没有event.path属性。

chrome:

image-20211130160232134

firefox:

image-20211130160315326image-20211130160315326

由上面两幅图可见火狐浏览器下打印的event事件对象是没有path属性的。

解决方案:

方案一:

百度寻找答案,发现很多人都给出如下的方案:

e.path || (e.composedPath && e.composedPath())

e.path是Chrome单独支持的属性,不属于MDN的标准,所以在MDN上搜不到event.path,但是composedPath是标准的属性。在MDN上解释如下:

image-20211130160852048

点击查看MDN关于composedPath的介绍

高兴的将上述代码拿到项目中尝试发现,WTF?怎么是空数组?(难道是自定义事件的锅吗?在Vue中不行)

方案二:

在分析FireFox的event对象时发现,event.target对象中的parentNode就是上层的父元素DOM节点。

image-20211130161522305

于是准备自己将所有的冒泡元素收集起来,以下composedPath方法就是具体的实现过程:

composedPath (e) {
  // 存在则直接return
  if (e.path) { return e.path }
  // 不存在则遍历target节点
  const target = e.target
  e.path = []
  while (target.parentNode !== null) {
    e.path.push(target)
    target = target.parentNode
  }
  // 最后补上document和window
  e.path.push(document, window)
  return e.path
}

然后在项目中使用这个方法做一个兼容即可。(真坑!!!!)

综上,方案一不可行,可能是vue-draggable组件库自定义事件对象的锅,原生js可能有效,需要进一步验证。方案二可行。