私は最も素晴らしいアイデアを探しています。焦点は効率です-ループの束を避けてみましょう=)
ライブラリはありません。これは純粋なJSの天才の練習です。ただし、これを実現する場合は、ライブラリ内から関数を自由に参照してください。くだらない古いブラウザ(つまり、IE)へのフォールバックの必要はありません。
セットアップ
イベントの委任を作成しようとしています。この要素内で発生する各イベントタイプ(クリック、mouseenterなど)のコンテナ要素(コンテキスト)にイベントリスナーをバインドしています。リスナーは関数を参照します。これを「ルート」と呼びます。
個別に作成された、次のようなオブジェクトがあります(例)。
myarr['click']['.myclass'] = functionReference1;
myarr['click']['#myid'] = functionReference2;
myarr['click']['div>a'] = functionReference3;
route
テイク(ここevent.type
では「クリック」)してmyarrに移動し、すべてのclick
レコードを取得します。route
次に、各セレクターキーをループして、それを。と照合しevent.target
ます。一致する場合は、関数参照が呼び出されcallback
ます。
これはすべてうまくいっています。かなり速く、簡単です。
質問
は、セレクターキーevent.target
に一致する要素の子である可能性があります。その親がコンテキスト要素との間にあるかどうかを判断するために、クレイジーで滑らかなブードゥー黒魔術を探しています。できれば、いくつかのネイティブブラウザ機能。event.target
理想的には、例として、私はの線に沿って何かをすることができます
context.querySelectorAll(key + " " + event.target);
しかし、明らかに、私が知る限り、オブジェクトをquerySelectorAllに渡すことはできません。
何が試されたのか
2つの方法が試されました。両方とも動作します。どちらもきれいではありません。
1)
一致するものが見つかるまで、event.target.parentNodeをループします。このトートはそれを行いますが、既存のループ内にループを作成します。ページにいくつかのセレクターキーと多くの要素があると、SLOWになり始めます。
if (event['target'].matchesSelector(key)) {
//do callback
} else {
var et = event['target'];
while (et['parentNode'] !== null and et['parentNode'] !== this) {
et = et['parentNode'];
if (et.matchesSelector(key)) {
//do callback
break;
}
}
}
2)
範囲を使用します。私はこれをかなり誇りに思っていますが、同じマルチループの問題があります。パフォーマンスをあまりテストしていませんが、ここで発生することはたくさんあります。セレクターキーに一致する要素がたくさんある場合、これはおそらく効率を損なうことになります。
if (event['target'].matchesSelector(key)){
//do callback
} else {
var range2 = document.createRange();
range2.selectNode(event.target);
var range = document.createRange();
var allthese = document.querySelectorAll(key)
for (var i = 0; i < allthese.length; i++){
range.selectNode(allthese[i]);
if (range2.compareBoundaryPoints(range2.START_TO_START, range) && range2.compareBoundaryPoints(range2.END_TO_END, range) <= 0){
//do callback
break;
}
}
}
MAGIC VOODOO-私にいくつか見つけてください、そして私が再び担当者を持っているとき、私は大きな報奨金を作成します。