Path 在 Firefox 中运行时没有定义

当我在 Firefox 中运行 event.path[n].id时,我得到了这个错误,它可以在其他浏览器中工作。

路径未定义

51783 次浏览

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>

In my tests (updated May 2018), neither IE11 nor Legacy Edge (v44 or earlier, before the Chromium update that starts with v79) supports either path or composedPath. Firefox supports composedPath. Chrome supports both path (it was Google's original idea) and composedPath. According to MDN recent versions of all major browsers apart from IE11 support composedPath as of January 2020.

So I don't think you can get the path information directly on IE11 (or Legacy Edge). You can, obviously, get the path via e.target.parentNode and each subsequent parentNode, which is usually the same, but of course the point of path/composedPath is that it's not always the same (if something modifies the DOM after the event was triggered but before your handler got called).

如果没有在浏览器中实现,您可以创建自己的 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;
}
}

返回的值相当于 Google Chrome 的 event.path。

例如:

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


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

这个函数用作 Event.composedPath()Event.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);
}

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

为了解决我的问题,我使用了 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()
}
}

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