Node.compareDocumentPositionが素晴らしい
と呟いていたら、 id:caisui さんが
と教えてくれた。
と教えてくれた。
広範囲にイベントを取得して、イベント発生元がどの要素に含まれるかで処理を変えたい時があって、そんな時は親ノードを辿って調べるという面倒なことをしていた。これとはおさらばしたいということで、compareDocumentPosition
について調べてみた。
The return value is a bitmask with the following values:
DOCUMENT_POSITION_DISCONNECTED = 0x01; DOCUMENT_POSITION_PRECEDING = 0x02; DOCUMENT_POSITION_FOLLOWING = 0x04; DOCUMENT_POSITION_CONTAINS = 0x08; DOCUMENT_POSITION_CONTAINED_BY = 0x10;Node.compareDocumentPosition - MDC Doc Center
引用の通り、比較するとビットの合計値が返ってくる。
また、ドキュメント上に載っていないけど、DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20
ってのもある。
比較ノードをa、比較対象をbとしてa.compareDocumentPosition(b)
をすると以下の様な結果になる。
aとbの関係 | 返り値 | ||
---|---|---|---|
同じノード | 0 | ||
a の子孫に b | 20((Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY)) | |
a の祖先に b | 10((Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS)) | |
a の兄弟(弟) に b | 4*1 | ||
a の兄弟(兄) に b | 2*2 | ||
同一ドキュメントにない | 32以上((Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_DISCONNECTED | ??? 実装によって異なる)) |
ってことで、以下の様な感じでコードが書けそう。
var elm = document.getElementById("elm_1"); window.addEventListener("click", function (event) { var res = elm.compareDocumentPosition(event.target); if (res == 0 || res & Node.DOCUMENT_POSITION_CONTAINED_BY) { // elmまたはelm内のノードがクリックされた時の処理 } }, false);