ドキュメントの場所の比較

ドキュメントの場所の比較
<br />2 年前に PPK が投稿した素晴らしいブログ記事では、contains() メソッドと compareDocumentPosition() メソッドがそれぞれのブラウザーでどのように機能するかが説明されています。それ以来、私はこれらの方法について多くの研究を行い、多くの機会にそれらを使用してきました。これらは、多くのタスク(特に、構造を持つ DOM セレクターの抽象化)に非常に役立つことがわかります。
1. DOMElement.contains(DOMNode)
このメソッドは元々、DOM ノードが別の DOM 要素に含まれているかどうかを判断するために IE で使用されていました。
このメソッドは、CSS セレクターのトラバーサル (「#id1 #id2」など) を最適化するときに役立ちます。 getElementById を介して要素を取得し、.contains() を使用して #id1 に実際に #id2 が含まれているかどうかを判断できます。
注: DOM ノードと DOM 要素が一致している場合、.contains() は true を返しますが、要素にそれ自身を含めることはできません。
Internet Explorer、Firefox、Opera、Safari で実行できるシンプルな実行可能ラッパーがあります。
関数は(a, b)を含む{
a.contains を返します ? a != b && a.contains(b) : !!(a.compareDocumentPosition(arg) & 16);
}

2. NodeA.CompareDocumentPosition(NodeB)
このメソッドは DOM レベル 3 仕様の一部であり、2 つの DOM ノードの相対的な位置を決定できます。このメソッドは .contains() よりも強力です。このメソッドの 1 つの応用例としては、DOM ノードを特定かつ正確な順序で並べ替えることが挙げられます。
この方法を使用すると、要素の位置に関する一連の情報を決定できます。この情報はすべてビット コード (ビット、バイナリ ビットとも呼ばれます) として返されます。
それらについてはほとんど知られていない。ビットコードとは、複数のデータを 1 つの数値 (翻訳者注: 0 または 1) として保存することです。最終的には個々の数字をオン/オフにして、最終結果を得ることになります。
以下は、NodeA.compareDocumentPosition(NodeB) から返される結果と取得できる情報です。
ビット数の意味
000000 0 要素は一貫している
000001 1 ノードが異なるドキュメント内にあります (または 1 つがドキュメント外にあります)
000010 2 ノードBはノードAより前にある
000100 4 ノードAはノードBより前にある
001000 8 ノードBにはノードAが含まれる
010000 16 ノードAにはノードBが含まれる
100000 32 ブラウザのプライベート使用 つまり、次のような結果になると考えられます。
<div id="a">
<div id="b"></div>
</div>
<スクリプト>
アラート( document.getElementById("a").compareDocumentPosition(document.getElementById("b")) == 20);
</スクリプト>

ノード A に別のノード B が含まれ、B (16) が含まれ、B (4) の前に来ると、最終結果は数値 20 になります。ビットに何が起こるかを見れば、理解が深まります。
000100 (4) 010000 (16) = 010100 (20)
これは間違いなく、最もわかりにくい DOM API メソッドを理解するのに役立ちます。もちろん、彼の価値は十分に認められています。
DOMNode.compareDocumentPosition が Firefox と Opera で利用できるようになりました。ただし、IE で実行するために使用できるトリックがいくつかあります。
// ポジションの比較 - MIT ライセンス、John Resig
関数 comparePosition(a, b){
a.compareDocumentPosition を返しますか?
a.CompareDocumentPosition(b) : ドキュメントの位置を比較します。
a. 含まれていますか?
( a != b && a.contains(b) && 16 )
( a != b && b.contains(a) && 8 )
( a.sourceIndex >= 0 && b.sourceIndex >= 0 ?
(a.sourceIndex < b.sourceIndex && 4)
(a.sourceIndex > b.sourceIndex && 2) :
1 ) :
0;
}

IE では、使用できるメソッドとプロパティがいくつか提供されています。まず、.contains() メソッド (前に説明したように) を使用して、包含 (16) または包含される (8) の結果を取得します。 IE には、すべての DOM 要素に、ドキュメント内の要素の位置に対応する .sourceIndex プロパティもあります (例: document.documentElement.sourceIndex == 0)。この情報があれば、前面(2)と背面(4)の 2 つの compareDocumentPosition パズルを完成させることができます。さらに、要素が現在のドキュメントにない場合、.sourceIndex は -1 になり、別の答え (1) が得られます。最後に、このプロセスを外挿することで、要素がそれ自身と等しい場合はヌル ビット コード (0) が返されることを判断できます。
この機能は、Internet Explorer、Firefox、Opera で動作します。しかし、Safari では機能が壊れています (contains() メソッドしかなく、.sourceIndex プロパティがないため)。contains (16)、is contains by (8) のみを取得でき、その他の結果は壊れていることを示す (1) を返します)。
PPK は、getElementsByTagNames メソッドを作成して新しい機能を利用できるようにする優れた例を提供します。これを新しい方法に適応させてみましょう:

これを使用して、サイトのディレクトリを次の順序で構築できるようになりました。
タグ名ごとに要素を取得します("h1, h2, h3");
Firefox と Opera は、このアプローチを実装するために何らかの取り組みを行っています。今後も、より多くのブラウザが登場し、物事が前進していくことを期待しています。
文書の位置の比較
// オリジナルは PPK quirksmode.org より
関数 getElementsByTagNames(リスト、要素) {
elem = elem || ドキュメント;
var tagNames = list.split(','), 結果 = [];
( var i = 0; i < tagNames.length; i ) {
タグを要素ごとに取得します。
( var j = 0; j < tags.length; j ) の場合
結果をpush( tags[j] );
}
結果を返します。sort(function(a, b){
3 - (comparePosition(a, b) & 6) を返します。
});
}

<<:  Dockerはローカルイメージとコンテナの保存場所を設定します

>>:  CSS スクロールバースタイル変更コード

推薦する

JavaScript の構成と継承の説明

目次1. はじめに2. プロトタイプチェーン継承3. コンストラクタの継承4. 組み合わせ継承1. ...

VMware で Nginx+KeepAlived クラスタ デュアルアクティブ アーキテクチャを展開する際の問題と解決策

序文負荷分散には nginx を使用します。アーキテクチャのフロントエンドまたは中間層として、トラフ...

MySQL テーブルを削除するときに外部キー制約を無視するシンプルな実装

テーブルを削除することはあまり一般的ではありませんが、特に外部キーの関連付けがあるテーブルの場合は、...

div タグ内の要素の margin-top が無効である場合の解決策

タイトル通りです。その質問は非常に奇妙です。要素の親タグはdivで、幅や高さなどの属性は設定されてい...

PXEを使用してCentOS7.6を自動的にインストールする方法の詳細なチュートリアル

1. 需要ベースには 300 台の新しいサーバーがあり、CentOS7.6 オペレーティング システ...

Windows (x86、64 ビット) で MySQL 5.7.17 無料インストール バージョンをアップグレードするための詳細なチュートリアル

Laravel 5.4 のデフォルトの utf8mb64 文字エンコーディングをサポートするには、M...

Vue ライフサイクルの紹介とフック関数の詳細な説明

目次Vueライフサイクルの紹介とフック機能VUEライフサイクルフックVue ライフサイクルの紹介作成...

MySQL 8.0.11 の新機能の紹介

MySQL 8.0 for Windows v8.0.11 公式無料バージョン 64 ビット1. デ...

クリックナンバーゲームを実装するネイティブJS

参考までに、クリックナンバーゲームをネイティブJSで実装しました。具体的な内容は以下のとおりです。最...

Vue で Google サードパーティ ログインを実装するためのサンプル コード

目次1. 開発者プラットフォームの構成問題を解決する1. 開発者プラットフォームの構成1. 開発者プ...

MySQL 5.7 における基本的な JSON 操作ガイド

序文プロジェクトのニーズにより、ストレージ フィールドは JSON 形式で保存されます。プロジェクト...

MySQLのファジークエリのような遅い速度を解決する方法

質問: インデックスは作成されているのに、Like ファジー クエリがまだ遅いのはなぜですか?インデ...

Vue+echarts で積み上げ棒グラフを実現

この記事では、積み上げ棒グラフを実装するためのVue+echartsの具体的なコードを参考までに紹介...

独自のネイティブ JavaScript ルーターを作成する方法

目次序文導入JavaScript 履歴 API独自のネイティブJSルーティングを実装するHistor...

VMware 仮想マシンのネットワークの問題の解決方法

目次1. 問題の説明2. 問題解決1. 仮想マシンシステムのインストール時にネットワークがない場合2...