jQuery .each()向后


441

我正在使用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开始,等等。这可能吗?

Answers:


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

10
应该是重要的注意的是,指数不会逆转,因此,如果你只想要做的最后三个,例如,你不能指望<li>Item 5</li>有0的指数
探路者

8
戴维·安德烈斯(David Andres):可能您忘了在li之前添加额外的$()。我犯了这个错误,并收到了“ undefined func”。
Michal-Areda-net 2014年

2
@DavidAndres:您错过了.get()将jQuery包装的数组转换为普通JS数组的方法。JS数组具有.reverse()
堆积

1
注意: Array.reverse()都将在适当位置修改数组并返回反向数组。因此,此解决方案实际上依赖于$()。get()返回一个新数组,而不是对某些内部jQuery或DOM数组的引用。在此示例的范围内,可能是安全的选择。注意事项编码器。
鲍勃·斯坦

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对象时具有数字属性和length属性,因此javascript可以对其进行索引并将数组函数应用于jQuery实例?
mlhDev 2012年

5
应该是重要的注意的是,指数不会逆转,因此,如果你只想要做的最后三个,例如,你不能指望<li>Item 5</li>有0的指数
探路者

1
@Matthew-是的,您理解正确。该代码确实确实复制了对over 的引用。许多JavaScript数组方法都可以在看起来像数组的任何对象上正常工作-也就是说,如果该对象具有和数字索引属性。不依赖于数组的某些内部表示;它访问使用正常的阵列,,等就像你会写自己的阵列码。Array.prototype.reversejQuery.prototype.reverse.lengthreverse.length[0][1]
Michael Geary

8
实例化一个新的Array只是为了获取其reverse方法,这不是浪费吗?Array.prototype.reverse例如,仅复制对函数的引用会更快jQuery.fn.reverse = Array.prototype.reverse;吗?不是那么简短和“聪明”,而是更有效率?诚然,在当今闪电般的浏览器中这可能并不明显,但仍然...
zachelrath

3
@zachelrath是的,我无法再将结果分开。看来20%只是a幸。请记住,您只设置了一次功能,因此实例化仅发生一次,从那里设置了功能。
桑迪·吉福德


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

在这里演示

一种将jQuery与反向结合使用的方法是:

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

这个演示在这里

一种选择是使用length(与该选择器匹配的元素数),然后使用index每次迭代的来从那里下来。然后,您可以使用以下代码:

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

这个演示在这里

还有一个,就是那种与上面的一个:

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 2013年

你是对的。无法链接,因此不是有效的插件。尽管已稍微改善了代码,将减量器移入了条件。
James Westgate


5

需要对$ .each进行反向操作,因此我使用了Vinay的想法:

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

工作很好,谢谢


这是不对的。这应该是$.each(collection.reverse(), ...)
索菲·阿尔珀特

@Ben Alpert-您的评论有缺陷,因为collection不是一个真正的数组
vsync

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

您也可以尝试

var arr = [].reverse.call($('li'))
arr.each(function(){ ... })
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.