2013-06-12 2 views
7

まず、いくつかの擬似擬似コード:

$("some-selector-logic").each(function() { 
    if (someLogic($(this))) { 
    return false; 
    } 
    // Otherwise do stuff related to $(this) 
}); 

someMoreExcitingCode(); 

この例では、各1を反復処理、いくつかのセレクタ論理に基づいてDOM要素のコレクションを取得しています。各要素について、someLogic()と呼んでいます。それがtrueを返した場合は、各ループを中止します。それ以外の場合、要素に対していくつかのロジックを実行し、次の要素に移動します。すべての要素を作業したら、引き続きsomeMoreExcitingCode()と呼んでください。

someMoreExcitingCode()を呼び出す前に、ループが途中で中止されたかどうかを知りたいと思います。

var aborted = false; 
$("..").each(function() { 
    if (someLogic($(this))) { 
    aborted = true; 
    return false; 
    } 
}); 

をしかし、jQueryのは、別の方法でこの情報を私に提供しなければならないように、これは、私にずさんな感じ:もちろん、あなたがこのような何かを行うことができます。これを達成するための慣用的な方法はありますか?

+0

私はこの問題を解決するために他の方法に遭遇していません –

+0

なぜあなたは知る必要がありますか?私は個人的にこのような要件に遭遇したことはありません。一見すると、それは臭い/漏れのようになります。多分あなたが取り組んでいるより大きな問題を解決する良い方法があるでしょう。 –

+0

私はあなたがすでに持っているもののバリエーションは、カウンタだと思いますが、すでに持っているものを上回っていることから、それから利点が見えません。 – TGH

答えて

3

jQuery関数は、呼び出されたオブジェクトの同じコレクションを返す傾向があるため(連鎖を許可するため)、each()関数がその情報を返す方法はありません - それはすでにjQueryオブジェクトを返しています他のメソッド呼び出しを連鎖させることができます。

あなたが提供した情報に基づいて、この情報を得るために外部フラグまたはカウンタ変数を使用する際に問題は見られません。 についてもう少し詳しくお伝えいただければ、なぜを知っておく必要がありますか?より有用な提案をすることができます。あなたは本当に、本当にabortブールを回避したい場合

var aborted = Array.prototype.some.call($(".foo"), function(el) { 
    if ($(el).hasClass('bar')) { 
     return true; 
    } 
}); 

jsfiddle

2

$.each()については何も魔法はありません。それは単純な関数であり、必要なものを実行するか、実行しないかのどちらかです。そうでない場合、コード例のように変数を設定することに何も問題はありません。そして、あなたが必要とするものを正確に実行する独自のeach()関数を書くことに何も問題はありません。これは、ループを実行してコールバック関数を呼び出すほんの数行のコードです。

ここではjQuery 1.10.1で$.each()のソースコードは次のとおりです。このコードで

// args is for internal usage only 
each: function(obj, callback, args) { 
    var value, 
     i = 0, 
     length = obj.length, 
     isArray = isArraylike(obj); 

    if (args) { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.apply(obj[ i ], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.apply(obj[ i ], args); 

       if (value === false) { 
        break; 
       } 
      } 
     } 

    // A special, fast, case for the most common use of each 
    } else { 
     if (isArray) { 
      for (; i < length; i++) { 
       value = callback.call(obj[ i ], i, obj[ i ]); 

       if (value === false) { 
        break; 
       } 
      } 
     } else { 
      for (i in obj) { 
       value = callback.call(obj[ i ], i, obj[ i ]); 

       if (value === false) { 
        break; 
       } 
      } 
     } 
    } 

    return obj; 
}, 

唯一の複雑さは、それはそれらのそれぞれのための2つの異なるケースで、オブジェクトと配列の両方を処理しているという事実から来ています。あなたが扱っているケースでは

、それはつまるところ:あり、その多くのコードがあるだけではない、とあなたがやりたいことしていない場合、あなたは簡単に似た独自のものを書くことができ

 for (; i < length; i++) { 
      value = callback.call(obj[ i ], i, obj[ i ]); 

      if (value === false) { 
       break; 
      } 
     } 

あなたが必要とするものを正確に行うイテレータ。

単純なforループを使用することもできます。

function doExcitingStuff() { 
    var $elements = $("some-selector-logic"); 
    for(var i = 0; i < $elements.length; i++) { 
     var $element = $($elements[i]); 
     if(someLogic($element)) 
      return; 
     // Otherwise do stuff related to $element 
    } 
    someMoreExcitingCode(); // only runs if the loop completes 
} 

これは本当にすべてがあなたのコードを最もクリーンにするかによって異なります。あなたは$.each()を使用するか、自分で書くことができます。

0

たぶんとしてエレガントではないあなたが望むだろうとして、しかし、あなたはArray.prototype.some使用することができます

$("..").removeClass('aborted').each(function() { 
    if(someLogic($(this))) { 
     $(this).addClass('aborted'); 
     return false; 
    } 
}); 

if($("..").find('aborted').length) { 
    //each was aborted 
} 
else { 
    //each ran to completion 
} 

しかし、これは実質的にDOMを使用してブーリアン状態を登録しますjs varを設定する。

個人的には、私は弾を噛んで、あなたのabort = trueのアイデアを使用します。

0

、あなたは効率性ではない気:

関連する問題