web-dev-qa-db-ja.com

FirefoxおよびVue.jsでevent.pathが未定義

まず、Vue.jsとNode.jsを使用しています

Firefoxに問題があります。

私が使う event.path[n].idとFirefoxでエラーが発生します

event.path未定義

ただし、他のブラウザでは正常に機能します。

どうしてか分かりますか?

31
Hanson

pathオブジェクトのEventプロパティは非標準です。標準的な同等物は composedPath で、これはメソッドです。しかし、それは新しいものです。

そのため、次のようにフォールバックすることもできます:

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

ブラウザーから提供されない場合、明らかにパス情報は得られませんが、古い方法と新しい標準的な方法の両方を使用できるため、最適なクロスブラウザーを実行できます。

例:

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>

私のテスト(2018年5月に更新)では、IE11もEdgeもpathまたはcomposedPathのいずれもサポートしていません。 FirefoxはcomposedPathをサポートしています。 Chromeはpath(Googleのオリジナルのアイデア)とcomposedPathの両方をサポートしています。

したがって、IE11またはEdgeで直接パス情報を取得できるとは思わない。明らかに、e.target.parentNodeおよび後続の各parentNodeを介してパスを取得できます。これは通常ですが、もちろんpath/composedPathは、always同じではないことです(イベントがトリガーされた後、ハンドラーが呼び出される前に何かがDOMを変更する場合)。

55
T.J. Crowder

ブラウザーに実装されていない場合は、独自のcomposePath関数を作成できます。

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

返される値は、Google Chromeのevent.pathと同等です。

例:

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

    var path = event.path || (event.composedPath && event.composedPath()) || composedPath(event.target);
});
22

この関数は、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);
}
7
Mr.7

同じ問題がありました。 html要素の名前が必要です。 In Chromeパスで名前を取得します。FirefoxではcomposePathを試しましたが、異なる値を返します。

私の問題を解決するために、これを使用しましたe.target.nodeNametarget関数を使用すると、Chrome、Firefox、およびSafariでHTML要素を取得できます。

これはVueの私の機能です:

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

ComposePath()を使用し、IEのポリフィルを使用します。 https://Gist.github.com/rockinghelvetica/00b9f7b5c97a16d3de75ba99192ff05c

上記のファイルを含めるか、コードを貼り付けます:

// 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);

次に使用します:

var path = event.path || (event.composedPath && event.composedPath());
0
Komal