繁体   English   中英

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

[英]Detecting “runs” of DOM elements in jQuery

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

从示例中可以看出,我只想包装li.foo dom元素的“运行”(其中有两个或更多li.foo元素连续。

我不确定通过jQuery实现这一目标的最好/最有效的方法(或者只是普通的javascript)。

示例: 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>');
});

method and include the original using the andSelf() method, then wrap them using the wrapAll() method. 循环遍历.foo元素,如果前一个元素不是 .foo ,并且它后面至少有1个.foo ,那么使用nextUntil() 方法获取所有下一个.foo元素并包含原始使用andSelf() 方法,然后使用wrapAll() 方法包装它们。


method when there's a previous .foo() . 更新: 这将更有效,因为它避免了以前的.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>');
});

使用这样的东西:

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

以递归方式检查编写一个检查下一个元素的函数,直到找到运行结束。

不确定这对性能有多好:

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

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

编辑添加:

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

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

工作示例: 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);
  });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM