JQuery .each() backwards

JavascriptJqueryArraysReverse

Javascript Problem Overview


I'm using JQuery to select some elements on a page and then move them around in the DOM. The problem I'm having is I need to select all the elements in the reverse order that JQuery naturally wants to select them. For example:

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

I want to select all the li items and use the .each() command on them but I want to start with Item 5, then Item 4 etc. Is this possible?

Javascript Solutions


Solution 1 - Javascript

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

Solution 2 - Javascript

I present you with the cleanest way ever, in the form of the world's smallest jquery plugin:

jQuery.fn.reverse = [].reverse;

Usage:

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

-All credit to Michael Geary in his post here: http://www.mail-archive.com/[email protected]/msg04261.html

Solution 3 - Javascript

You can do

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

followed by

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

Solution 4 - Javascript

Here are different options for this:

First: without 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;
});

###Demo here

... and with jQuery:

You can use this:

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

Demo here

Another way, using also jQuery with reverse is:

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

This demo here.

One more alternative is to use the length (count of elements matching that selector) and go down from there using the index of each iteration. Then you can use this:

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

This demo here

One more, kind of related to the one above:

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

Demo here

Solution 5 - Javascript

I prefer creating a reverse plug-in eg

jQuery.fn.reverse = function(fn) {       
   var i = this.length;
   
   while(i--) {
       fn.call(this[i], i, this[i])
   }
};

Usage eg:

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

Solution 6 - Javascript

If you don't want to save method into jQuery.fn you can use

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

Solution 7 - Javascript

Needed to do a reverse on $.each so i used Vinay idea:

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

worked nicely, thanks

Solution 8 - Javascript

You cannot iterate backwards with the jQuery each function, but you can still leverage jQuery syntax.

Try the following:

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

Solution 9 - Javascript

I found Array.prototype.reverse unsuccessful with objects, so I made a new jQuery function to use as an alternative: jQuery.eachBack(). It iterates through as the normal jQuery.each() would, and stores each key into an array. It then reverses that array and performs the callback on the original array/object in the order of the reversed keys.

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

Solution 10 - Javascript

You can also try

var arr = [].reverse.call($('li'))
arr.each(function(){ ... })

Solution 11 - Javascript

I think u need

.parentsUntill()

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJack MillsView Question on Stackoverflow
Solution 1 - JavascriptJoe ChungView Answer on Stackoverflow
Solution 2 - JavascriptWaldo HamptonView Answer on Stackoverflow
Solution 3 - JavascriptVinay SajipView Answer on Stackoverflow
Solution 4 - JavascriptSergioView Answer on Stackoverflow
Solution 5 - JavascriptJames WestgateView Answer on Stackoverflow
Solution 6 - JavascriptyurakisView Answer on Stackoverflow
Solution 7 - JavascriptfinklezView Answer on Stackoverflow
Solution 8 - JavascriptDavid AndresView Answer on Stackoverflow
Solution 9 - JavascriptNRTRXView Answer on Stackoverflow
Solution 10 - JavascriptmattyfewView Answer on Stackoverflow
Solution 11 - JavascriptJimmy MView Answer on Stackoverflow