Javascript 在 Firefox 中运行的 event.path 未定义
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39245488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
event.path is undefined running in Firefox
提问by Hanson
When I run event.path[n].id
in Firefox, I get this error. It works in other browsers.
当我event.path[n].id
在 Firefox 中运行时,出现此错误。它适用于其他浏览器。
event.path undefined
event.path 未定义
回答by T.J. Crowder
The path
property of Event
objects is non-standard. The standard equivalent is composedPath
, which is a method. But it's new.
对象的path
属性Event
是非标准的。标准等价物是composedPath
,这是一种方法。但它是新的。
So you may want to try falling back to that, e.g.:
所以你可能想尝试回到那个,例如:
var path = event.path || (event.composedPath && event.composedPath());
if (path) {
// You got some path information
} else {
// This browser doesn't supply path information
}
Obviously that won't give you path information if the browser doesn't supply it, but it allows for both the old way and the new, standard way, and so will do its best cross-browser.
显然,如果浏览器不提供路径信息,它不会为您提供路径信息,但它允许旧方式和新的标准方式,因此将尽其所能地跨浏览器。
Example:
例子:
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 Edge supports either path
or composedPath
. Firefox supports composedPath
. Chrome supports both path
(it was Google's original idea) and composedPath
.
在我的测试中(2018 年 5 月更新),IE11 和 Edge 都不支持path
或composedPath
. 火狐支持composedPath
. Chrome 支持path
(这是 Google 的最初想法)和composedPath
.
So I don't think you can get the path information directly on IE11 or Edge. You can, obviously, get the path via e.target.parentNode
and each subsequent parentNode
, which is usuallythe same, but of course the point of path
/composedPath
is that it's not alwaysthe same (if something modifies the DOM after the event was triggered but before your handler got called).
所以我不认为你可以直接在IE11或Edge上获取路径信息。显然,您可以通过e.target.parentNode
和每个后续获取路径parentNode
,这通常是相同的,但当然path
/ 的重点composedPath
是它并不总是相同的(如果在触发事件之后但在您的处理程序被调用之前修改了 DOM )。
回答by Guillaume Jasmin
You can create your own composedPath function if it's not implemented in the browser:
如果浏览器中没有实现,您可以创建自己的 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;
}
}
The returned value is equivalent to event.path of Google Chrome.
返回值相当于谷歌浏览器的 event.path。
Example:
例子:
document.getElementById('target').addEventListener('click', function(event) {
var path = event.path || (event.composedPath && event.composedPath()) || composedPath(event.target);
});
回答by Mr.7
This function serves as a polyfill for Event.composedPath()
or Event.Path
此函数用作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);
}
回答by Komal
Use composePath() and use a polyfill for IE: https://gist.github.com/rockinghelvetica/00b9f7b5c97a16d3de75ba99192ff05c
使用 composePath() 并为 IE 使用 polyfill:https://gist.github.com/rockinghelvetica/00b9f7b5c97a16d3de75ba99192ff05c
include above file or paste code:
包括上面的文件或粘贴代码:
// 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);
and then use:
然后使用:
var path = event.path || (event.composedPath && event.composedPath());
回答by Benjamin Pe?a Olvera
I had the same issue. I need the name of the html element. In Chrome I get the name with path. In firefox I trieed with composedPath but it return a different value.
我遇到过同样的问题。我需要 html 元素的名称。在 Chrome 中,我得到了带有路径的名称。在 Firefox 中,我尝试使用 compositionPath 但它返回不同的值。
For solved my problem I used this e.target.nodeName. With targetfunction you can retrieve the HTML element in Chrome, Firefox and Safari.
为了解决我的问题,我使用了这个e.target.nodeName。使用目标函数,您可以在 Chrome、Firefox 和 Safari 中检索 HTML 元素。
This is my fucntion in Vue:
这是我在 Vue 中的功能:
selectFile(e) {
this.nodeNameClicked = e.target.nodeName
if (this.nodeNameClicked === 'FORM' || this.nodeNameClicked === 'INPUT' || this.nodeNameClicked === 'SPAN') {
this.$refs.singlefile.click()
}
}