在jQuery中检测DOM元素的“运行”

5

如何使用jQuery检测DOM元素的运行情况是最好的呢?

例如,如果我有以下项目列表:

<ol>
  <li class="a"></li>
  <li class="foo"></li>
  <li class="a"></li>
  <li class="a"></li>
  <li class="foo"></li>
  <li class="foo"></li>
  <li class="foo"></li>
  <li class="a"></li>
  <li class="foo"></li>
  <li class="foo"></li>
  <li class="foo"></li>
</ol>

假设我想要获取所有的 li.foo 元素,并将它们封装在自己的 <ol> 块(或任何其他包装器)中,以达到如下所示的效果。

<ol>
  <li class="a"></li>
  <li class="foo"></li>
  <li class="a"></li>
  <li class="a"></li>
  <li><ol>
    <li class="foo"></li>
    <li class="foo"></li>
    <li class="foo"></li>
  </ol></li>
  <li class="a"></li>
  <li><ol>
    <li class="foo"></li>
    <li class="foo"></li>
    <li class="foo"></li>
  </ol></li>
</ol>

从例子中可以看出,我只想包装连续出现了2个或更多的li.foo dom元素。

我不确定用jQuery(或者纯javascript)实现这个功能最好/最有效的方式是什么。

4个回答

3

Example: http://jsfiddle.net/kNfxs/1/

$('ol .foo').each(function() {
    var $th = $(this);
    var nextUn = $th.nextUntil(':not(.foo)');
    if(!$th.prev('.foo').length && nextUn.length)
        nextUn.andSelf().wrapAll('<li><ol></ol></li>');
});

循环遍历所有的.foo元素,如果前一个元素不是.foo,并且它后面至少有1个.foo,那么使用nextUntil()(文档)方法获取所有接下来的.foo元素,然后使用andSelf()(文档)方法包含原始元素,并使用wrapAll()(文档)方法将它们包装起来。

更新: 当前的做法会更加高效,因为它避免了在前面有.foo时使用nextUntil()(文档)方法。

示例: http://jsfiddle.net/kNfxs/2/

$('ol .foo').each(function() {
    var $th = $(this);
    if($th.prev('.foo').length) return; // return if we're not first in the group
    var nextUn = $th.nextUntil(':not(.foo)');
    if( nextUn.length)
        nextUn.andSelf().wrapAll('<li><ol></ol></li>');
});

0

可以使用类似这样的代码:

$(li).each(function(){
if($(this).next().hasClass('foo')){
---- Recursively check until the end of the run has been found ----
}
});

为了递归地检查,请编写一个函数,该函数检查下一个元素,直到找到运行的结尾。

0

工作示例:http://jsfiddle.net/v8GY8/

为后人留下:

// Takes a jQuery collection and returns an array of arrays of contiguous elems
function groupContiguousElements( $elems ){
  var groups = [];
  var current, lastElement;
  $elems.each(function(){
    if ($(this).prev()[0] == lastElement ){
      if (!current) groups.push( current=[lastElement] );
      current.push( this );
    }else{
      current = null;
    }
    lastElement = this;
  });
  return groups;
}

var groups = groupContiguousElements( $('li.foo') );
$.each( groups, function(){
  var wrapper = $('<ol>').insertBefore(this[0]);
  $.each(this,function(){
    wrapper.append(this);
  });
});

0

不确定这对性能的影响如何:

var $foo = $('.foo + .foo');
$foo.add($foo.prev());

$foo将是“.foo运行集合”

补充说明:

我想到了一个更简单的方法:

var $foo = $('.foo + .foo').prev('.foo').andSelf();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接