Hatena::ブログ(Diary)

hogehoge @teramako RSSフィード

 | 

2011-01-08

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 の子孫に b20*1
a の祖先に b10*2
a の兄弟(弟) に b4*3
a の兄弟(兄) に b2*4
同一ドキュメントにない32以上*5

表だとちょっと分かりにくいので図にすると

f:id:teramako:20110108185742p:image

ってことで、以下の様な感じでコードが書けそう。

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

*1:Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINED_BY

*2:Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_CONTAINS

*3:Node.DOCUMENT_POSITION_FOLLOWING

*4:Node.DOCUMENT_POSITION_PRECEDING

*5:Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | Node.DOCUMENT_POSITION_DISCONNECTED | ??? 実装によって異なる

teramakoteramako 2011/01/12 00:29 なんか変なブックマークタグが付いているな。
この記事は、ECMASCriptの話でもnode.jsの話でもないですよ〜

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

 |