event.path is undefined running in Firefox
The path
property of Event
objects is non-standard. The standard equivalent is the composedPath
method. But it was new when the question was asked (2016); it's well-established as of this update in January 2023.
So you may want to try composedPath
and fall back to path
(or just use composedPath
now it's established):
// Written in ES5 for compatibility with browsers that weren't obsolete
// yet when the question was posted, although they are now
var path = event.composedPath ? event.composedPath() : event.path;
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:
// Written in ES5 for compatibility with browsers that weren't obsolete
// yet when the question was posted, although they are now
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, first using the standard
// method if possible, falling back to non-standard `path`
var path = event.composedPath ? event.composedPath() : event.path;
// Show it if we got it
if (path) {
console.log("Path (" + path.length + ")");
Array.prototype.forEach.call(path, function(entry) {
console.log(entry === window ? "window" : entry.nodeName);
});
}
});
.as-console-wrapper {
max-height: 100% !important;
}
<div id="target">Click me</div>
event.path is undefined running in Firefox
The path
property of Event
objects is non-standard. The standard equivalent is the composedPath
method. But it was new when the question was asked (2016); it's well-established as of this update in January 2023.
So you may want to try composedPath
and fall back to path
(or just use composedPath
now it's established):
// Written in ES5 for compatibility with browsers that weren't obsolete
// yet when the question was posted, although they are now
var path = event.composedPath ? event.composedPath() : event.path;
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:
// Written in ES5 for compatibility with browsers that weren't obsolete
// yet when the question was posted, although they are now
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, first using the standard
// method if possible, falling back to non-standard `path`
var path = event.composedPath ? event.composedPath() : event.path;
// Show it if we got it
if (path) {
console.log("Path (" + path.length + ")");
Array.prototype.forEach.call(path, function(entry) {
console.log(entry === window ? "window" : entry.nodeName);
});
}
});
.as-console-wrapper {
max-height: 100% !important;
}
<div id="target">Click me</div>
How to use e.path in addEventListener cross-browser?
Firefox equivalent is e.composedPath()
document.querySelectorAll('input[type="text"]').forEach(elt => {
elt.addEventListener("change", e => {
let path = e.path || e.composedPath()
localStorage.setItem(path[0]?.name, path[0]?.value);
});
});
If both of them are not supported in the browser still it wont give an error but set Item undefined:undefined because of the usage path?.property get ElementById not working on firefox?
document.getElementById()
compatibility with any browser is unquestionable that isn't the problem. See this answer about .path
compatibility with Firefox.
Replace event.path[0]
with event.target
.
function takeName(event) {
let filename = event.target.files[0].name;
document.getElementById("txtComment").value = filename;
}
<form id="Apply" name="Apply" method="post" enctype="multipart/form-data" action="applyLeave.php">
Get upload filename to textarea:
<p><textarea rows="3" cols="30" name="txtComment" id="txtComment" class="valid"></textarea></p>
<p>Select image to upload: <input type="file" onchange="takeName(event)" name="fileToUpload" id="fileToUpload"></p>
<p><input type="submit" value="Submit" name="submit"></p>
</form>
MouseEvent.path equivalent in Firefox & Safari
It's not available, but if you really would like to have this property, then you could extend the native prototype of the Event object like so:
if (!("path" in Event.prototype))
Object.defineProperty(Event.prototype, "path", {
get: function() {
var path = [];
var currentElem = this.target;
while (currentElem) {
path.push(currentElem);
currentElem = currentElem.parentElement;
}
if (path.indexOf(window) === -1 && path.indexOf(document) === -1)
path.push(document);
if (path.indexOf(window) === -1)
path.push(window);
return path;
}
});
However if I were you, I wouldn't extend the prototype - I would create a function like mentioned above instead.Also I would change Event.prototype to MouseEvent.prototype if you want to cover only those types of events.
determine event path in DOM Event bubbling
event.path || event.composedPath()
event.path
Dis/Un-covered by a note in the polymer project documentation and via an HTML5Rocks article, path
is a family tree in the form of an Array
.It appears to be an "extension to the event
interface" only exposed via the Web Component Shadow DOM, and is standard only in this respect (apparently), not a lot of documentation seems available, and it isn't exposed (by default) in all browsers.
event.composedPath()
to the rescue!
Another question about the use of path
was answered with a suggestion to use composedPath
...
MDN's documentation about event.composedPath()
describes it as follows:
TheIt is described by WHATWG in their "DOM specs" documentation about the "event path" as follows:composedPath()
method of the Event interface returns the event’s path which is an array of the objects on which listeners will be invoked. This does not include nodes in shadow trees if the shadow root was created with itsShadowRoot.mode
closed.
Returns the invocation target objects of event’s path (objects on which listeners will be invoked), except for any nodes in shadow trees of which the shadow root’s mode is "closed" that are not reachable from event’s currentTarget.Can I use... states that browser support of
composedPath()
is widespread, with all modern major browsers supporting its use, and MDN agrees.WHATWG's documentation about "dispatching events" details the conditions under which "event's path
" will have items appended.
Details correct December 30, 2022
Practical demo
const green = document.getElementById( 'green' ),
msg = document.querySelector( 'output' );
document.getElementById( 'red' ).addEventListener( 'click', evt => {
msg.innerHTML = '"' + evt.target.id + '" got poked, and "green" was' +
/* access to the event path */
( ~evt.composedPath().indexOf( green ) ? '' : "<b>n't</b>" )
+ ' in the path.';
} );
div { display: inline-block; padding: 1em 3em 1em 1em; cursor: pointer }
output { font-family: monospace; display: block; margin-top: 1em }
#red { background: red }
#green { background: green }
#blue { background: blue }
<div id="red">
<div id="green">
<div id="blue"></div>
</div>
</div>
<output>Poke the DOM!</output>
How to get VueJS $event in Firefox when element is clicked?
e.path is a chrome only attribute.
try replacing e.path[0] with e.target
if that doesn't work there is the composedPath..
look at this question
Alternative to composedPath for Edge
You can try to check this polyfill may help to get composed path.
// 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);
use it like below:var path = event.path || (event.composedPath && event.composedPath());
References:(1) event.path undefined with Firefox and Vue.js
(2) rockinghelvetica/composedpath.polyfill.js
Other than that I did not got any alternative or work around to get Event.Composedpath for IE and Edge browsers.
Related Topics
Why How to Not Throw Inside a Promise.Catch Handler
If (Key in Object) or If(Object.Hasownproperty(Key)
How to Deeply Merge Two Object Values by Keys
How to Make a Directive Update Ng-Model on Jquery on Event
Why Is There a 'Null' Value in JavaScript
Play 2.X: How to Make an Ajax Request with a Common Button
How Do We Set Remote in Typeahead.Js
Why Are Await and Async Valid Variable Names
How to Get Ssl Certificate Details Using JavaScript
How to Take Advantage of Callback Functions for Asynchronous Xmlhttprequest
Is There a Mechanism to Loop X Times in Es6 (Ecmascript 6) Without Mutable Variables
How to Sum the Values of a JavaScript Object
Differencebetween React Native and React
JavaScript Settimeout and Loops
Calling a JavaScript Function Recursively
Detect If an Element Is Visible with Jquery
Why Do I Need to Await an Async Function When It Is Not Supposedly Returning a Promise
Way to Know If User Clicked Cancel on a JavaScript Onbeforeunload Dialog