Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

event.path is undefined running in Firefox

When I run event.path[n].id in Firefox, I get this error. It works in other browsers.

event.path undefined

like image 450
Hanson Avatar asked Aug 31 '16 09:08

Hanson


2 Answers

The path property of Event objects is non-standard. The standard equivalent is composedPath, which is a method. But it's new.

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 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).

like image 136
T.J. Crowder Avatar answered Sep 18 '22 13:09

T.J. Crowder


You can create your own composedPath function if it's not implemented in the browser:

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.

Example:

document.getElementById('target').addEventListener('click', function(event) {      var path = event.path || (event.composedPath && event.composedPath()) || composedPath(event.target); }); 
like image 30
Guillaume Jasmin Avatar answered Sep 19 '22 13:09

Guillaume Jasmin