Event.Path Is Undefined Running in Firefox

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:

The 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 its ShadowRoot.mode closed.

It is described by WHATWG in their "DOM specs" documentation about the "event path" as follows:

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



Leave a reply



Submit