2017年2月22日水曜日

二つの変数に入っているエレメントが同じものを参照しているか判定する

「同じ」と判定する基準としては
1.outerHTMLの値が一致する
2.document.bodyからのDOMツリー内ポジションが一致する
3.タグ名が一致する
などなど色々あり、どういう意味で「同じ」ものが必要かによって判定基準を変える必要があります。

この記事で扱うのは「変数Aから参照しているエレメントにinsertBeforeすると変数Bから参照しているエレメント側でも子要素が増える」という意味での「同じ」エレメントかどうかを判定する基準を用いた判定用関数です。

以下ソース
<html>
<body>
<div>aaa</div>
<div>aaa</div>
<div></div>
</body>
<script>
isEqual=function(elemA, elemB){
// elemAとelemBが同一エレメントを参照しているならtrueを返す。それ以外はfalseを返す。
var d=document.createElement('div'), FI='firstChild', iT='innerText'
elemA.insertBefore(d.removeNode(true), elemA[FI])
var str=d[iT]=1111111, sw=false
while(!sw){
if(elemB[FI][iT]!=str){ break }
str=d[iT]=1234567
if(elemB[FI][iT]!=str){ break }
sw = true
}
d.removeNode(true)
return sw
}
cn=document.body.childNodes
div0 = cn[0]
div1 = cn[1]
div2 = cn[2]
div2.innerText = [
'div0.outerHTML : ' + div0.outerHTML,
'',
'div1.outerHTML : ' + div1.outerHTML,
'',
'isEqual(div0,div1) : ' + isEqual(div0,div1),
'',
'isEqual(div0,div0) : ' + isEqual(div0,div0),
'',
'div0==div0 : ' + (div0==div0),
'',
'div0==div1 : ' + (div0==div1)
].join('\n')
</script>
</html>
view raw isEqual.hta hosted with ❤ by GitHub



動作結果



単純に「div0==div0」とか「div0==div1」とかした結果がisEqualの結果と一致しているので、別にisEqual関数なんて定義しなくてもいいんじゃね?とも思いますが、何をもってtrueと判定されているのか資料が無いので、意図したとおりの判定を確実に実施するisEqualを使うことにします。

ちなみにisEqualはJavaScriptがシングルスレッド限定ということを利用したロジックになっています。今後、DOMアクセスに対してもマルチスレッドが可能になるかは不明ですが、もしそうなると運悪く同時にinnerTextが1111111から1234567へ奇跡的なタイミングで変更されると判定ミスします。現実的に考えてまずそんなことは起きないと思うので大丈夫と判断します。

0 件のコメント:

コメントを投稿