web-dev-qa-db-fra.com

event.path undefined avec Firefox et Vue.js

J'utilise d'abord Vue.js et Node.js

J'ai un problème avec Firefox.

J'utilise event.path[n].id et avec Firefox j'obtiens une erreur

event.path undefined

Mais cela fonctionne bien dans d'autres navigateurs.

Avez-vous une idée pourquoi?

21
Hanson

La propriété path des objets Event est non standard. L'équivalent standard est composedPath , qui est une méthode. Mais c'est nouveau.

Donc, vous voudrez peut-être essayer de revenir à cela, par exemple:

var path = event.path || (event.composedPath && event.composedPath());
if (path) {
    // You got some path information
} else {
    // This browser doesn't supply path information
}

Évidemment, cela ne vous donnera pas d’informations sur le chemin si le navigateur ne le fournit pas, mais cela permet à la fois l’ancien et le nouveau moyen, et fera de ce fait son meilleur navigateur.

Exemple:

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>

Dans mes tests (mis à jour en mai 2018), ni IE11 ni Edge ne prennent en charge ni path ni composedPath. Firefox supporte composedPath. Chrome prend en charge path (c'était l'idée initiale de Google) et composedPath.

Donc, je ne pense pas que vous puissiez obtenir les informations de chemin directement sur IE11 ou Edge. Vous pouvez évidemment obtenir le chemin via e.target.parentNode et chaque parentNode suivante, qui est habituellement identique, mais le point de pathcomposedPath est que ce n'est pas toujours _/toujours identique (si quelque chose modifie le DOM après le déclenchement de l'événement mais avant que votre gestionnaire ne soit appelé).

40
T.J. Crowder

Vous pouvez créer votre propre fonction compoundPath si elle n'est pas implémentée dans le navigateur:

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;
    }
}

La valeur renvoyée est équivalente à event.path de Google Chrome.

Exemple:

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

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

Cette fonction sert de polyfill pour Event.composedPath() ou 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);
}
6
Mr.7

J'ai eu le même problème. J'ai besoin du nom de l'élément html. Dans Chrome, je reçois le nom avec le chemin. Dans Firefox, je trie avec compoundPath mais il retourne une valeur différente.

Pour résoudre mon problème, j'ai utilisé ceci e.target.nodeName . Avec target function, vous pouvez récupérer l’élément HTML dans Chrome, Firefox et Safari.

Ceci est ma fonction dans Vue:

selectFile(e) {
        this.nodeNameClicked = e.target.nodeName
        if (this.nodeNameClicked === 'FORM' || this.nodeNameClicked === 'INPUT' || this.nodeNameClicked === 'SPAN') {
          this.$refs.singlefile.click()
      }
    }
0