jQuery .each()逆方向


442

JQueryを使用してページ上のいくつかの要素を選択し、DOM内でそれらを移動しています。私が抱えている問題は、JQueryが本来選択したい逆の順序ですべての要素を選択する必要があることです。例えば:

<ul>
   <li>Item 1</li>
   <li>Item 2</li>
   <li>Item 3</li>
   <li>Item 4</li>
   <li>Item 5</li>
</ul>

すべてのli項目を選択して.each()コマンドを使用したいのですが、項目5、次に項目4などから始めたいのですが、これは可能ですか?

回答:


681
$($("li").get().reverse()).each(function() { /* ... */ });

10
あなたが唯一の最後の三つをやりたいと思っているので、場合、インデックスが逆転されていないことに注意することが重要である必要があり、例えば、あなたが期待することはできません<li>Item 5</li>0のインデックス持っている
パスファインダー

8
David Andresへ:liの前に$()を追加するのを忘れているかもしれません。私はこの間違いをして、「undefined func」を受け​​取りました。
ミハル-areda-net 2014年

2
@DavidAndres:.get()jQueryでラップされた配列を通常のJS配列に変換するを逃しました。JS配列にはがあり.reverse()ます。
スタック型の2015

1
注意: Array.reverse()両方とも、配列変更し、逆の配列を返します。したがって、このソリューションは実際には$()。get()が新しい配列を返すことに依存しており、内部のjQueryまたはDOM配列への参照ではありません。おそらく、この例の範囲内で安全な賭けです。警告コーダー。
Bob Stein

404

世界最小のjqueryプラグインの形で、これまでで最もクリーンな方法を紹介します。

jQuery.fn.reverse = [].reverse;

使用法:

$('jquery-selectors-go-here').reverse().each(function () {
    //business as usual goes here
});

-ここの彼の投稿でのMichael Gearyへのすべての信用:http : //www.mail-archive.com/discuss@jquery.com/msg04261.html


わかりました、それはすばらしいことですが、なぜ機能するのですか?Array.prototype.reverseをjQuery.prototype.reverseにコピー(大まかに言えば)していて、それが呼び出されたとき、thisオブジェクトは数値プロパティと長さプロパティを持っているので、javascriptはそれにインデックスを付け、配列関数をjQueryインスタンスに適用できますか?
mlhDev

5
あなたが唯一の最後の三つをやりたいと思っているので、場合、インデックスが逆転されていないことに注意することが重要である必要があり、例えば、あなたが期待することはできません<li>Item 5</li>0のインデックス持っている
パスファインダー

1
@マシュー-はい、あなたはそれを正しく理解しています。このコードは、実際にコピーしない参照Array.prototype.reverseオーバーにしますjQuery.prototype.reverse。JavaScriptの配列メソッドの多くは、配列のように見えるオブジェクトでも問題なく機能します。つまり、オブジェクトに.length数値のインデックスプロパティがある場合です。reverse配列の内部表現に依存しません。それは、通常使用してアレイにアクセスし.length[0][1]ちょうどあなたがあなた自身を書きたい配列のコードのようになど。
Michael Geary 2013年

8
reverseメソッドを取得するためだけに新しい配列をインスタンス化するのは無駄ではありませんか?Array.prototype.reverseたとえば、関数への参照をコピーするだけの方が高速ではないでしょうjQuery.fn.reverse = Array.prototype.reverse;か?短くて「賢い」わけではありませんが、より効率的ですか?確かに、これはおそらく今日の超高速ブラウザでは気づかないでしょうが、それでも...
zachelrath

3
@zachelrathええ、私はもはや結果を区別することはできません。20%はまぐれだったようです。関数の設定は1回だけなので、インスタンス化は1回だけ行われ、そこから関数が設定されます。
Sandy Gifford


20

これにはさまざまなオプションがあります。

最初:jQueryなし:

var lis = document.querySelectorAll('ul > li');
var contents = [].map.call(lis, function (li) {
    return li.innerHTML;
}).reverse().forEach(function (content, i) {
    lis[i].innerHTML = content;
});

デモはこちら

...そしてjQueryで:

あなたはこれを使うことができます:

$($("ul > li").get().reverse()).each(function (i) {
    $(this).text( 'Item ' + (++i));
});

デモはこちら

もう1つの方法は、jQueryを逆に使用することです。

$.fn.reverse = [].reverse;
$("ul > li").reverse().each(function (i) {
    $(this).text( 'Item ' + (++i));
});

このデモはこちら

もう1つの方法は、length(そのセレクターに一致する要素の数)を使用しindex、各反復のを使用してそこから下に行くことです。次に、これを使用できます:

var $li = $("ul > li");
$li.each(function (i) {
    $(this).text( 'Item ' + ($li.length - i));
});

このデモはこちら

もう一つ、上記1に関連する種類:

var $li = $("ul > li");
$li.text(function (i) {
    return 'Item ' + ($li.length - i);
});

デモはこちら


14

私はリバースプラグインを作成することを好みます

jQuery.fn.reverse = function(fn) {       
   var i = this.length;

   while(i--) {
       fn.call(this[i], i, this[i])
   }
};

使用例:

$('#product-panel > div').reverse(function(i, e) {
    alert(i);
    alert(e);
});

私もこのアイデア/コードが好きですが、投票数の多い回答のようにチェーン可能なオブジェクト(逆)は返されません:)それでも、セットアップ方法としては間違いなく良い方法です
Ian

あなたが正しいです。チェーン化できないため、有効なプラグインではありません。ただし、コードを少し改善し、デクリメンターを条件に移動しました。
James Westgate


5

$ .eachを逆にする必要があるため、Vinayのアイデアを使用しました。

//jQuery.each(collection, callback) =>
$.each($(collection).get().reverse(), callback func() {});

うまくいきました、ありがとう


これは正しくありません。これはちょうどである必要があります$.each(collection.reverse(), ...)
ソフィーアルパート


4

各関数をjQueryで逆方向に反復することはできませんが、jQuery構文を利用できます。

以下を試してください:

//get an array of the matching DOM elements   
var liItems = $("ul#myUL li").get();

//iterate through this array in reverse order    
for(var i = liItems.length - 1; i >= 0; --i)
{
  //do Something
}

2

私が見つかりました。Array.prototype.reverse私が代わりとして使用する新しいjQueryの機能を作ったので、オブジェクトで失敗しました:jQuery.eachBack()。通常のように反復し、jQuery.each()各キーを配列に格納します。次に、その配列を反転し、反転したキーの順序で元の配列/オブジェクトにコールバックを実行します。

jQuery.eachBack=function (obj, callback) {
    var revKeys=[]; $.each(obj,function(rind,rval){revKeys.push(rind);}); 
    revKeys.reverse();
    $.each(revKeys,function (kind,i){
        if(callback.call(obj[i], i, obj[i]) === false) {    return false;}
    });
    return obj;
}   
jQuery.fn.eachBack=function (callback,args) {
    return jQuery.eachBack(this, callback, args);
}

-2

私はあなたが必要だと思います

.parentsUntill()

1
なぜそう思うの?そして、それをどのように使用しますか?
ベルギ

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.