event.path 未定义在 Firefox 中运行

Posted

技术标签:

【中文标题】event.path 未定义在 Firefox 中运行【英文标题】:event.path is undefined running in Firefox 【发布时间】:2020-08-20 10:45:44 【问题描述】:

当我在 Firefox 中运行 event.path[n].id 时,我收到此错误。它适用于其他浏览器。

event.path 未定义

【问题讨论】:

更一般地用于 Firefox Web 控制台和“未定义”:Chrome/Firefox console.log always appends a line saying 'undefined' 【参考方案1】:

Event 对象的path 属性是非标准的。标准等效项是composedPath,这是一种方法。但它是新的。

所以你可能想尝试回退到那个,例如:

var path = event.path || (event.composedPath && event.composedPath());
if (path) 
    // You got some path information
 else 
    // This browser doesn't supply path information

显然,如果浏览器不提供路径信息,它不会为您提供路径信息,但它允许旧方式和新的标准方式,因此会尽其所能地跨浏览器。

例子:

document.getElementById("target").addEventListener("click", function(e) 
  // Just for demonstration purposes
  if (e.path) 
    if (e.composedPath) 
      console.log("Supports `path` and `composedPath`");
     else 
      console.log("Supports `path` but not `composedPath`");
    
   else if (e.composedPath) 
    console.log("Supports `composedPath` (but not `path`)");
   else 
    console.log("Supports neither `path` nor `composedPath`");
  
  
  // Per the above, get the path if we can
  var path = e.path || (e.composedPath && e.composedPath());
  
  // Show it if we got it
  if (path) 
    console.log("Path (" + path.length + ")");
    Array.prototype.forEach.call(
      path,
      function(entry) 
        console.log(entry.nodeName);
      
    );
  
, false);
<div id="target">Click me</div>

在我的测试(2018 年 5 月更新)中,IE11 和 Legacy Edge(v44 或更早版本,在从 v79 开始的 Chromium 更新之前)都不支持pathcomposedPath。 Firefox 支持composedPath。 Chrome 支持path(这是谷歌最初的想法)和composedPath。 According to MDN 除 IE11 外,所有主流浏览器的最新版本都支持 composedPath,截至 2020 年 1 月。

所以我认为您无法直接在 IE11(或 Legacy Edge)上获取路径信息。显然,您可以通过e.target.parentNode 和随后的每个parentNode 获取路径,这通常是相同的,但当然path/composedPath 的意义在于它不是总是相同(如果在触发事件之后但在调用您的处理程序之前修改了 DOM)。

【讨论】:

嘿!感谢您的回答,但 event.ComposedPath 在 Chrome 和 Firefox 中返回 undefined @Hanson:对,再说一次,这是 new 标准。 Chrome 支持旧方式 (path)。查看更新的答案,我认为 Firefox(或 IE,未测试 Edge)上没有此信息。 看来FF现在已经支持composedPath()了(测试版本59.0.3)。 @PeterHerdenborg - 确实!我已经更新了。 Chrome 现在也支持(以前只支持path)。还测试了 Edge,很遗憾两者都不支持。 @Esger - 不,composed 是 something else entirely,与 pathcomposedPath() 无关。【参考方案2】:

我有同样的问题。我需要 html 元素的名称。在 Chrome 中,我得到带有路径的名称。在 Firefox 中,我尝试使用 composedPath,但它返回不同的值。

为了解决我的问题,我使用了 e.target.nodeName。使用 target 函数,您可以在 Chrome、Firefox 和 Safari 中检索 HTML 元素。

这是我在Vue.js中的函数:

selectFile(e) 
        this.nodeNameClicked = e.target.nodeName
        if (this.nodeNameClicked === 'FORM' || this.nodeNameClicked === 'INPUT' || this.nodeNameClicked === 'SPAN') 
          this.$refs.singlefile.click()
      
    

【讨论】:

【参考方案3】:

使用 composePath() 并为 IE 使用 polyfill: https://gist.github.com/rockinghelvetica/00b9f7b5c97a16d3de75ba99192ff05c

包含以上文件或粘贴代码:

// Event.composedPath
(function(e, d, w) 
  if(!e.composedPath) 
    e.composedPath = function() 
      if (this.path) 
        return this.path;
       
    var target = this.target;

    this.path = [];
    while (target.parentNode !== null) 
      this.path.push(target);
      target = target.parentNode;
    
    this.path.push(d, w);
    return this.path;
    
  
)(Event.prototype, document, window);

然后使用:

var path = event.path || (event.composedPath && event.composedPath());

【讨论】:

【参考方案4】:

此函数用作 Event.composedPath()Event.Path 的 polyfill

function eventPath(evt) 
    var path = (evt.composedPath && evt.composedPath()) || evt.path,
        target = evt.target;

    if (path != null) 
        // Safari doesn't include Window, but it should.
        return (path.indexOf(window) < 0) ? path.concat(window) : path;
    

    if (target === window) 
        return [window];
    

    function getParents(node, memo) 
        memo = memo || [];
        var parentNode = node.parentNode;

        if (!parentNode) 
            return memo;
        
        else 
            return getParents(parentNode, memo.concat(parentNode));
        
    

    return [target].concat(getParents(target), window);

【讨论】:

我已经测试过这种方法,一切都像魅力一样!【参考方案5】:

如果没有在浏览器中实现,您可以创建自己的composedPath函数:

function composedPath (el) 

    var path = [];

    while (el) 

        path.push(el);

        if (el.tagName === 'HTML') 

            path.push(document);
            path.push(window);

            return path;
       

       el = el.parentElement;
    

返回值相当于谷歌浏览器的event.path。

例子:

document.getElementById('target').addEventListener('click', function(event) 

    var path = event.path || (event.composedPath && event.composedPath()) || composedPath(event.target);
);

【讨论】:

这实际上是不一样的,有时 parentElement 返回 null 在某些情况下, event.path/composePath() 会给你完整的路径.. 不是path/composedPath的实现。它错过了它们的关键方面(你不能 polyfill)。 接受的答案错过了此功能在边缘工作,因为也不支持组合路径。真不错。 这在开放的影子根中不起作用。我正在寻找一个 Edge polyfill,它可以为我提供 Web 组件中的源 dom 节点,而不是文档。

以上是关于event.path 未定义在 Firefox 中运行的主要内容,如果未能解决你的问题,请参考以下文章

ReferenceError:Firefox 中的事件未定义错误

Firefox 8 for Mac 出现问题:window.name 未定义

Firefox 4 中的 JQuery 未定义和 $ 未定义错误 [关闭]

Google Maps API v3:在Firefox中未触发自定义标记的点击事件

自定义字体未在用作背景图像的 SVG 模式中显示

自定义 CSS webkit 滚动条在 Firefox 浏览器中不起作用