2010-11-26 18 views
0

いくつかの条件/機能が満たされている最も近い次の要素を取得するにはどうすればよいですか?同様:jQuery:nextEl = someEl.next(function(){... return true/false;})?

nextEl = someEl.next(function() {... return true to return this from next() });

私はjQueryのAPIで.next()メソッドは、引数としての機能をサポートしていることを認識していませんよ。 whileループを行わずに、このように書くためのトリックがありますか?

また、すべての要素を最初に選択してから、filter()を使用することは望ましくありません。これは、パフォーマンスの観点からは最適ではありません。

+0

あなたはそれが別のセレクタによって満たされなかった状態であることを完全に確信していますか? – zincorp

+0

はい。また、最初にすべての要素を選択してからfilter()を使用することは望ましくありません。これはパフォーマンスの観点からは最適ではありません。 – tillda

+0

ネイティブコードバージョンを 'nextMatch()'と呼ばれるプラグインに変換するように答えを更新したので、条件がそれよりも多く実行されず、nextAll()で次のすべての兄弟をフェッチしません。 '。 – user113716

答えて

2

using .nextAll()、次にuse .filter()のすべての要素を取得し、条件の結果を返します。条件がtrueになると、要素は保持されます。

次に、the .first()に一致するように絞り込みます。

nextEl = someEl.nextAll().filter(function() { 
    return (someCondition); 
}).first(); 

た場合、または

は、試験された多くの要素があるでしょう、そしてあなたは、条件が満たされたとき .each()、その後、 return false;を使用し、条件にすべてのそれらの余分回実行する必要はありません。これにより、ループが停止します。

var nextEl; 

someEl.nextAll().each(function() { 
    if(someCondition) { 
     nextEl = this; // reference the matched element 
     return false; // break the loop 
    } 
}); 

EDIT:あなたがすべて次の要素を選択したくない場合は、私がネイティブに行く、とwhileループを使用すると思い、このような何か:

var nextEl = someEl[0]; 

while(nextEl = nextEl.nextSibling) { 
    if(someCondition) { 
     break; 
    } 
} 

条件が満たされるとすぐにループが解除され、nextElへの最新の割り当てが要素になります。

条件が満たされない場合、要素がなくなるとループが終了し、はnullまたはundefined(いずれも覚えていません)です。

これは非常に簡単な方法です。


EDIT:

ここでの機能バージョンです。開始要素とテストを実行する関数を受け入れます。見つかった一致、つまりundefinedを返します。

function nextMatch(el, func) { 
    while(el = el.nextSibling) { 
     if(func()) { 
      return el; 
     } 
    } 
} 

    // nextEl will contain the match, or "undefined" 
var nextEl = nextMatch(someEl, function() { 
    return (someTest); 
}); 

var someOtherEl = nextMatch(someEl, function() { 
    return (someOtherTest); 
}); 

LAST EDIT:

私は、同様のプラグインにそれを作るかもしれない推測:

(function($) { 
    $.fn.nextMatch = function(func) { 
     return this.map(function() { 
      var el = this; 
      while(el = el.nextSibling) { 
       if(el.nodeType === 1 && func.call(el)) { 
        return el; 
       } 
      } 
     }); 
    } 
})(jQuery); 

var nextEl = someEl.nextMatch(function() { 
    return (someTest); 
}); 

だから、今ではjQueryのタイプのソリューションの多くはです。次のすべての兄弟をフェッチせず、一致が見つかるとwhileループが引き続き破損するため、パフォーマンスはさらに向上するはずです。

+0

これはうまくいきますが、すべての要素を選択するためのパフォーマンスペナルティがあります。 – tillda

+0

@tillda - 条件テストのペナルティか、要素を選択するだけですか?最初に満足した後に条件を停止する答えを加えました。 '.nextAll()'が必要ない場合は、whileループを使うことができます。私は更新を与えるでしょう。 – user113716

+0

実際に 'filter'の中の' return false; 'はループを破壊しません。 'filter'の結果からその要素を破棄します。したがって実際には、これは最後に一致する兄弟を選択します(これは(http://jsfiddle.net/cambraca/vQPC4/1/)を見てください) – cambraca

1

この試し:条件

nextEl = someEl.nextAll('.a').first().css('color', 'red'); 

は、それがクラスaを有すること、この場合であり、それは(単に指標として)赤色に変わり。

hereを見てください。

+0

申し訳ありませんが、私が欲しいものではありません。私は**関数**によって指定したいと思います。また、パフォーマンスのためにすべての要素を最初に一致させたくありません。 – tillda

+0

あなたは 'next()'を使ってそれを行うことができます: 'nextEl = someEl.next( '.a');' –

+1

@FrédéricHamidi:実際にはできません。次の要素が一致しない場合、それ以上は見えず、何も返されません。 – cambraca