JQuery .each () geriye doğru


442

Bir sayfadaki bazı öğeleri seçmek ve daha sonra DOM onları taşımak için JQuery kullanıyorum. Yaşadığım sorun, JQuery'nin doğal olarak onları seçmek istediği tüm öğeleri ters sırayla seçmem gerekiyor. Örneğin:

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

Tüm li öğelerini seçmek ve üzerlerinde .each () komutunu kullanmak istiyorum ancak önce Öğe 5, sonra Öğe 4 vb. İle başlamak istiyorum. Bu mümkün mü?

Yanıtlar:


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

10
Dizinin tersine çevrilmediğine dikkat etmek önemlidir, bu nedenle yalnızca son üçünü yapmak istiyorsanız, <li>Item 5</li>0 dizinine sahip olmayı bekleyemezsiniz .
pathfinder

8
David Andres'e: belki li önce $ () eklemeyi unutmuş olabilirsiniz. Bu hatayı yaptım ve "tanımsız fon" aldım.
Michal - wereda-net

2
@DavidAndres: .get()jQuery kaydırılmış dizisini sıradan bir JS dizisine dönüştüren özlüyorsunuz . JS dizisi vardır .reverse().
yığın

1
Dikkat: Array.reverse()hem diziyi yerinde değiştirir hem de ters diziyi döndürür. Yani bu çözüm aslında bazı dahili jQuery veya DOM dizisine başvuru değil , yeni bir dizi döndüren $ (). Get () yöntemine dayanır . Muhtemelen bu örneğin sınırları içinde güvenli bir bahis. Uyarı Kodlayıcı.
Bob Stein

404

Size dünyanın en küçük jquery eklentisi şeklinde şimdiye kadarki en temiz yolu sunuyoruz:

jQuery.fn.reverse = [].reverse;

Kullanımı:

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

- Michael Geary'a buradaki gönderisindeki tüm kredi: http://www.mail-archive.com/discuss@jquery.com/msg04261.html


Tamam, kabul ediyorum, ama neden işe yarıyor? Array.prototype.reverse dosyasını jQuery.prototype.reverse'e kopyalıyorsunuz (gevşekçe konuşuyorsunuz) ve thisnesne çağrıldığında nesne sayısal özelliklere ve length özelliğine sahip, bu nedenle javascript onu dizine ekleyebilir ve bir jQuery örneğine bir dizi işlevi uygulayabilir mi?
mlhDev

5
Dizinin tersine çevrilmediğine dikkat etmek önemlidir, bu nedenle yalnızca son üçünü yapmak istiyorsanız, <li>Item 5</li>0 dizinine sahip olmayı bekleyemezsiniz .
pathfinder

1
@Matthew - Evet, doğru anlıyorsun. Bu kod bir kopya yok gerçekten referansı için Array.prototype.reverseyanına jQuery.prototype.reverse. JavaScript dizi yöntemlerinin çoğu, bir diziye yeterince benzeyen herhangi bir nesne üzerinde iyi çalışır - nesnenin .lengthve sayısal dizin özelliklerinin olması. reversedizinin bazı iç temsillerine bağlı değildir; diziye .length, kendiniz yazacağınız dizi kodu gibi normal [0], [1]vb. kullanarak erişir .
Michael Geary

8
Sadece reverseyöntemini elde etmek için yeni bir Dizi başlatmak israf değil mi? Sadece işleve bir referansı kopyalamak daha hızlı olmaz mıydı Array.prototype.reverse, örneğin jQuery.fn.reverse = Array.prototype.reverse;? Kısa ve "akıllı" değil, daha verimli mi? Kuşkusuz bu, günümüzün yıldırım hızında tarayıcılarında muhtemelen fark edilmeyecek, ama yine de ...
zachelrath

3
@zachelrath Evet, artık sonuçlar arasında hiçbir ayrım yapamıyorum. Görünüşe göre% 20'si sadece bir şans. Unutmayın, işlevi yalnızca bir kez ayarladığınızdan, örnekleme yalnızca bir kez gerçekleşir, oradan işlev ayarlanır.
Sandy Gifford

64

Yapabilirsin

jQuery.fn.reverse = function() {
    return this.pushStack(this.get().reverse(), arguments);
}; 

bunu takiben

$(selector).reverse().each(...) 

14
Bu yaklaşım ilk olarak jQuery posta listesinde John Resig (jQuery geliştiricisi) tarafından önerilmiştir .
Chris Shouts

20

İşte bunun için farklı seçenekler:

İlk : jQuery olmadan:

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;
});

Burada demo

... ve jQuery ile:

Bunu kullanabilirsiniz:

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

Burada demo

Başka bir yol da jQuery ile tersini kullanmaktır:

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

Bu demo burada .

Bir başka seçenek de length(bu seçiciyle eşleşen öğe sayısı) kullanmak ve indexher bir yinelemeyi kullanarak oradan aşağı inmektir. Sonra bunu kullanabilirsiniz:

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

Bu demo burada

Bir tane daha , yukarıdakiyle ilgili:

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

Burada demo


14

Ters bir eklenti oluşturmayı tercih ederim.

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

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

Kullanım ör:

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

Ben de bu fikri / kodu seviyorum, ama yüksek oylanmış cevaplar gibi zincirlenebilir bir nesne (tersine çevrilmiş) dönmüyor :) Yine de, kesinlikle kurulum yöntemi için iyi bir yöntem
Ian

Haklısın. Zincirli değil, geçerli bir eklenti değil. Azaltıcı koşula taşıyarak kodu biraz geliştirdik.
James Westgate

8

Eğer yöntemi jQuery.fn içine kaydetmek istemiyorsanız kullanabilirsiniz

[].reverse.call($('li'));

Aradığım şey buydu.
Alexander Dixon

5

Vinay fikir kullanılan $ .each üzerinde bir ters yapmak gerekiyordu:

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

güzel çalıştı, teşekkürler


Bu doğru değil; bu sadece olmalı $.each(collection.reverse(), ...).
Sophie Alpert

@Ben Alpert - Yorumunuz kusurlu, çünkü koleksiyon gerçek bir dizi değil
vsync

4

Her işlev jQuery ile geriye doğru yinelenemez, ancak yine de jQuery sözdiziminden yararlanabilirsiniz.

Takip etmeyi dene:

//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

Bulduğum Array.prototype.reverseben alternatif olarak kullanmak için yeni bir jQuery işlevini yapılmış, böylece nesneler ile başarısız: jQuery.eachBack(). Normalde olduğu gibi yinelenir jQuery.each()ve her anahtarı bir dizide saklar. Daha sonra bu diziyi tersine çevirir ve orijinal dizi / nesne üzerinde geri arama tuşlarını sırasıyla geri çağırır.

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

Bence ihtiyacın var

.parentsUntill()

1
Neden öyle düşünüyorsun? Ve onu nasıl kullanacaksın?
Bergi

-2

Ayrıca deneyebilirsiniz

var arr = [].reverse.call($('li'))
arr.each(function(){ ... })
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.