IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

要素が document につながっているかを高速に調べる方法

とある要素が document につながっているかどうかを調べたい!

とりあえず、ほとんどすべてのブラウザで出来る方法としては、 parentNode で確認することができますね。

function isElementInDocument(node) {
  do {
    if (node === document) {
      return true;
    }
  } while (node = node.parentNode)
  return false;
}

でも

前の例だとちょっと遅いので contains や、 compareDocumentPosition を使うといいです!
コードにすると以下のような感じ

function isElementInDocument(node) {
  if (document === node) {
    return true
  }
  else if (document.compareDocumentPosition) {
    return !!(document.compareDocumentPosition(node) & 16)
  }
  else if (document.documentElement.contains) {
    var el = document.documentElement;
    return el === node || el.contains(node);
  }
  else {
    do {
      if (node === document) {
        return true;
      }
    } while (node = node.parentNode)
    return false;
  }
}

contains は IE 由来の関数で、 compareDocumentPosition は W3C で標準化されている方法です。
contains は document にはなくて、要素にしかないという点に注意ですね。
あと、 contains は引数も要素じゃないとダメなようですね。

というか><

compareDocumentPosition は、ビット列なんですがどのビットがなんだったのかを覚えられません><
Document Object Model Core

追記:

node.ownerDocument === document じゃだめなの?というのが多かったのでちょっと解説。
えーっと、この記事のユースケースは「document の子孫として存在するか」というものでした。伝わりにくくてすみません><
node.ownerDocument は node.parentNode が null のような場合(木として繋がっていない場合でも) document を返すので、この場合使えません。