次に一致する兄弟姉妹を効率よく、簡潔に見つける方法は?
質問
公式のjQuery APIにこだわると、与えられたセレクタにマッチする要素の次の兄弟を見つけるための、より簡潔で、しかし効率に劣らない方法は
nextAll
と
:first
擬似クラス?
私が公式APIと言ったとき、私は内部をハックしない、Sizzleに直接行く、ミックスにプラグインを追加する、などを意味します(私がそれをしなければならないことになるなら、それはそうですが、この質問はそういうことではありません。)。
例:この構造を考えると
<div>One</div>
<div class='foo'>Two</div>
<div>Three</div>
<div class='foo'>Four</div>
<div>Five</div>
<div>Six</div>
<div>Seven</div>
<div class='foo'>Eight</div>
もし私が
div
で
this
(おそらく
click
ハンドラでも何でも)、セレクタ "div.foo" に一致する次の兄弟 div を見つけたい場合、私はこれを行うことができます。
var nextFoo = $(this).nextAll("div.foo:first");
...そして、それは動作します(例えば、私が "Five" で始めた場合、それは "Six" と "Seven" をスキップして私のために "Eight" を見つけます)、しかしそれは不格好です、もし私がいくつかのセレクタのうちのどれかにマッチしたい場合、それはもっと不格好になります。(もちろん、これは ロット よりも簡潔です。)
私は基本的に欲しいです。
var nextFoo = $(this).nextMatching("div.foo");
...ここで
nextMatching
はセレクタの全範囲を受け入れることができます。私がいつも驚くのは
next(selector)
がこれを行わないことにいつも驚きますが、これは行いませんし、それが何を行うかについてドキュメントが明確になっているので、...
私はいつでもそれを書いて追加することができますが、そうして公開されたAPIにこだわると、物事はかなり非効率的になります。たとえば、ナイーブな
next
のループがあります。
jQuery.fn.nextMatching = function(selector) {
var match;
match = this.next();
while (match.length > 0 && !match.is(selector)) {
match = match.next();
}
return match;
};
...は
著しく
より遅い
よりも
nextAll("selector:first")
. それも当然といえば当然なのですが
nextAll
は全部を Sizzle に渡すことができますし、Sizzle は徹底的に最適化されています。上記の素朴なループは、あらゆる種類の一時的なオブジェクトを作成して捨て、セレクタを毎回再パースしなければなりません。
そしてもちろん、私はただ単に
:first
を末尾につけることもできます。
jQuery.fn.nextMatching = function(selector) {
return this.nextAll(selector + ":first"); // <== WRONG
};
...というのも、これは "div.foo" のような単純なセレクタでは動作しますが、私が話した "any of several" オプション、例えば "div.foo, div.bar" では失敗してしまうからです。
編集
: すみません、そう言うべきでした。最後に、私はちょうど
.nextAll()
を使って、その後に
.first()
を使用すると、jQueryは最初の1つを見つけるためにすべての兄弟を訪問しなければなりません。私は、最初のもの以外のすべての結果を捨てることができるように、リスト全体を通過するのではなく、一致したときに停止するようにしてほしいのです。(これは
は本当に
の最後のテストケースをご覧ください。
速度比較
の最後のテストケースを参照してください)。
よろしくお願いします。
どのように解決するのですか?
を渡すことができます。
複数セレクタ
に
.nextAll()
を使用し
.first()
をつけると、このようになります。
var nextFoo = $(this).nextAll("div.foo, div.something, div.else").first();
編集する
比較のために、ここでテストスイートに追加されます。
http://jsperf.com/jquery-next-loop-vs-nextall-first/2
この方法はとても高速です。というのも、単純な組み合わせで
.nextAll()
セレクタを可能な限りネイティブコードに渡し (現在のすべてのブラウザ)、結果セットの最初のものを取得するだけの単純な組み合わせだからです...。
方法
は、純粋に JavaScript で実行できるどのようなループよりも高速です。
関連
-
[解決済み] jquery mobileでページ中央のグリッド表示
-
[解決済み] 選択オプション「selected」を値で設定する
-
[解決済み] jQuery hasAttrで要素に属性があるかどうかをチェックする【重複あり
-
[解決済み] JQueryでラジオボタンがチェックされているかどうかを調べる?
-
[解決済み] jQuery UI DatePicker - 日付フォーマットの変更
-
[解決済み] jQueryで5秒待つには?
-
[解決済み] jQueryでフォームフィールドをクリアする
-
[解決済み] jQueryを使用してHTML要素を作成する最も効率的な方法は何ですか?
-
[解決済み】jQueryのクラスセレクタがない。
-
[解決済み] 個々のクラス名で 'starts with' セレクタを使用する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] jQueryでdata属性で要素を選択する
-
[解決済み] ユーザーがEnterキーを押してフォームを送信できないようにする
-
[解決済み] jQueryでPUT/DELETEリクエストを送信する方法は?
-
[解決済み] jQuery UI DatePicker - 日付フォーマットの変更
-
[解決済み] Twitter Bootstrapのモーダルウィンドウを閉じないようにする
-
[解決済み] jQueryで複数のCSS属性を定義するには?
-
[解決済み] チェックボックスがチェックされた場合のjQuery
-
[解決済み] jQueryの検証:デフォルトのエラーメッセージを変更する
-
[解決済み] jQueryでval()がchange()をトリガーしない
-
[解決済み] jQueryで<input type="text">のonchangeを実装するには?