检查jQuery对象是否有一些DOM元素的最快方法

Fastest way to check if a jQuery object has some DOM elements

本文关键字:元素 方法 DOM 对象 jQuery 是否 检查      更新时间:2023-09-26

我有一个带有一些DOM元素的jQuery对象。我取这个对象并对其元素进行排序。但有些元素有优先级,所以当我排序时,我不能让它们位于没有优先级的元素之下。

示例:

<!-- original list -->
<el id='2' /> <!-- has priority -->
<el id='0' /> <!-- has priority -->
<el id='3' /> <!-- has priority -->
<el id='1' /> <!-- no priority -->
<el id='4' /> <!-- no priority -->
<!-- wrong way to sort -->
<el id='0' /> <!-- has priority -->
<el id='1' /> <!-- no priority -->
<el id='2' /> <!-- has priority -->
<el id='3' /> <!-- has priority -->
<el id='4' /> <!-- no priority -->
<!-- right way to sort -->
<el id='0' /> <!-- has priority -->
<el id='2' /> <!-- has priority -->
<el id='3' /> <!-- has priority -->
<el id='1' /> <!-- no priority -->
<el id='4' /> <!-- no priority -->

我如何解决这个问题:

var elements = $(selector);
elements.sort(sort_by_id);
var priority_elements = get_prio_elements(); //That's the only way to know which are the elements with priority
var temp = $();
elements.each(function(){
    if(priority_elements.is(this))  //check if element are inside priority list
        temp = temp.add($(this));  //push element in elements object order
});
set_prio_elements(temp);

我的输出应该是temp对象。我的意思是:temp应该包含:

<el id='0' /> <!-- has priority -->
<el id='2' /> <!-- has priority -->
<el id='3' /> <!-- has priority -->

按此顺序。

问题是,对于大型列表(超过300+-),此代码的速度非常慢。我想知道如何改进这一点。

小提琴上的一个环节可以帮助理解。

难道不能在sort_function中检查元素的"priority"属性是否设置为"true"吗?

我首先将所有元素收集在两个数组中:一个表示priority='true',另一个表示相反的数组,对这些数组进行排序,然后将它们连接起来。


更新:我创造了这把小提琴,如果你喜欢的话,看看你能不能改编一下然后看看它是否更有资源效率
我猜是的,因为你不必再浏览整个"元素"对象,但我可能错了。

https://jsfiddle.net/virginieLGB/qev5r9yx/

更改内容:
1) 我们对两个对象进行排序

elements.sort(sort_by_id);
priority_elements.sort(sort_by_id);

2) 我们只是将优先级元素放回起始位置,删除它们,然后取消

  for( var i = elements.length - 1 ; i >= 0 ; i-- ) {
    var index = priority_elements.indexOf( elements[ i ] );
    if( index > -1 ) {
        var temp = elements[ i ];
        elements.splice( i , 1 );
      elements.unshift( temp );
      priority_elements.splice( index , 1 );
    }
  }

更新#2:

我的输出应该是临时对象。我的意思是:temp应该包含:
<el id='0' /> <!-- has priority -->
<el id='2' /> <!-- has priority -->
<el id='3' /> <!-- has priority -->

那么,你为什么不直接做呢

priority_elements.sort( sort_by_id );


因为基本上,你似乎在做的是获得优先级元素,然后在原始列表中检查它们是否有优先级,如果有,就保留它们。。。但你一开始就已经有了?还是我错过了什么?

理解JS代码实际在做什么很困难,因为您似乎错过了几个关键函数。

也就是说,您声明您想要的输出是先按元素的priority排序,然后按元素的id排序。您可以在单个sort()调用中执行此操作。

首先要注意,创建自己的属性是无效的,所以priority应该是data-priority。从那里,您可以实现自己的sort()逻辑,类似于以下内容:

$(selector).sort(function(a, b) {
    var $a = $(a), 
        $b = $(b), 
        aId = parseInt(a.id, 10), 
        bId = parseInt(b.id, 10);
    // sort by priority
    if ($a.data('priority') && !$b.data('priority'))
        return -1;
    else if (!$a.data('priority') && $b.data('priority'))
        return 1;
    // sort by id
    if (aId < bId)
        return -1;
    else if (aId > bId)
        return 1
    return 0;
});

工作示例

请注意,通过使用三元表达式可以大大缩短上面的内容,但我将其保留为冗长的内容,以便您可以清楚地看到发生了什么。