DOMおれおれAdvent Calendar 2015 – 16日目分
HTMLが以下のような構成だとして、 #origin
を起点に各要素との位置を比較してみます。
var origin = document.querySelector('#origin'); var parent = document.querySelector('#parent'); var result = origin.compareDocumentPosition(parent); console.log(!!(result & origin.DOCUMENT_POSITION_PRECEDING)); // => true console.log(!!(result & origin.DOCUMENT_POSITION_FOLLOWING)); // => false console.log(!!(result & origin.DOCUMENT_POSITION_CONTAINS)); // => true console.log(!!(result & origin.DOCUMENT_POSITION_CONTAINED_BY)); // => false console.log(!!(result & origin.DOCUMENT_POSITION_DISCONNECTED)); // => false
状態
node.DOCUMENT_POSITION_CONTAINS
みたいな感じで定義されています。
状態 | 定数 |
---|---|
#origin から見て先 |
DOCUMENT_POSITION_PRECEDING |
#origin から見て後 |
DOCUMENT_POSITION_FOLLOWING |
#origin から見て上 |
DOCUMENT_POSITION_CONTAINS |
#origin から見て下 |
DOCUMENT_POSITION_CONTAINED_BY |
#origin とは無関係 |
DOCUMENT_POSITION_DISCONNECTED |
前後関係はツリーを順々に見て行った場合のものになるので、兄弟でなくてもPRECEDINGないしFOLLOWINGになります。
無関係と判断されるのは所属するドキュメントツリー自体が別の場合ですかね。ノード生成の後、まだツリーに追加していない場合とか。
上記の他に、ブラウザーが独自に拡張できる値も用意されてるみたいです。
比較は &&
ではなく &
ビット演算子です。演算子の説明はしませんが、この仕組みのおかげで複数の状態を同時に持つ事ができます。
var result = origin.compareDocumentPosition(el); if (result & el.DOCUMENT_POSITION_FOLLOWING) { console.log('elが先に出てきます。'); } if (result & el.DOCUMENT_POSITION_CONTAINS) { // <-else ifじゃない console.log('elに含まれてます。'); }
諸々を確認した結果
vs ancestor
- PRECEDING
- CONTAINS
vs parent
- PRECEDING
- CONTAINS
vs elder
- PRECEDING
vs elder-child
- PRECEDING
vs younger
- FOLLOWING
vs child
- FOLLOWING
- CONTAINED_BY
vs descendant
- FOLLOWING
- CONTAINED_BY
vs younger-anscestor
- FOLLOWING
contains()
要素を含むかどうかだけなら origin.contains(target)
というAPIもあります。
環境
IE 9+。他は大丈夫そうです。