在 Firefox 中运行的 event.path 未定义

IT技术 javascript firefox
2021-02-08 01:42:30

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

event.path 未定义

5个回答

对象path属性Event是非标准的。标准等价物是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. 火狐支持composedPath. Chrome 支持path(这是 Google 的最初想法)和composedPath. 根据 MDNcomposedPath,截至 2020 年 1 月,除 IE11 支持外,所有主要浏览器的最新版本

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

@Esger - 不,完全composed别的东西,与path无关composedPath()
2021-03-15 01:42:30
现在似乎 FF 已经支持composedPath()(用 59.0.3 版测试)。
2021-03-25 01:42:30
嘿!感谢您的回答,但 event.ComposedPath 在 Chrome 和 Firefox 中返回 undefined
2021-04-03 01:42:30
@PeterHerdenborg - 确实如此!我已经更新了。Chrome 现在也支持(它曾经只支持path)。还测试了 Edge,很遗憾看到两者都不支持。
2021-04-03 01:42:30
@Hanson:是的,再次,这是标准。Chrome 支持旧方式 ( path)。请参阅更新的答案,我认为此信息在 Firefox(或 IE,未测试 Edge)上不可用。
2021-04-04 01:42:30

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

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);
});
这在开放的影子根中不起作用。我正在寻找一个 Edge polyfill,它可以为我提供 web 组件中的源 dom 节点,而不是文档。
2021-03-15 01:42:30
不是path/的实现composedPath它错过了它们的关键方面(你不能 polyfill)。
2021-03-26 01:42:30
这实际上并不相同,有时 parentElement 在某些情况下返回 null 并且 event.path/composePath() 会给你完整路径..
2021-03-27 01:42:30
接受的答案错过了这个功能在边缘工作,因为也不支持组合路径。非常好。
2021-03-27 01:42:30

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

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);
}
我已经测试了这种方法,一切都像魅力一样!
2021-03-15 01:42:30

使用 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());

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

为了解决我的问题,我使用了e.target.nodeName使用目标函数,您可以在 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()
      }
    }