简体   繁体   English

使用jQuery来包装元素组

[英]Use jQuery to wrap around groups of elements

I've got a list of elements and I want to use the header divs to separate them after the pages loaded up. 我有一个元素列表,我想在页面加载后使用标题div来分隔它们。 So the code below, 所以下面的代码,

<div class="header">Header 1</div>
<div class='test'>Test 1</div>
<div class='test'>Test 2</div>
<div class='test'>Test 3</div>
<div class="header">Header 2</div>
<div class='test'>Test 4</div>
<div class='test'>Test 5</div>
<div class='test'>Test 6</div>
<div class='test'>Test 7</div>
<div class='test'>Test 8</div>
<div class="header">Header 3</div>
<div class='test'>Test 9</div>
<div class='test'>Test 10</div>
<div class='test'>Test 11</div>
<div class='test'>Test 12</div>
<div class="header">Header 4</div>
<div class='test'>Test 13</div>
<div class='test'>Test 14</div>

Would become, 会成为,

<div class='wrap'>
<div class="header">Header 1</div>
<div class='test'>Test 1</div>
<div class='test'>Test 2</div>
<div class='test'>Test 3</div>
</div>
<div class='wrap'>
<div class="header">Header 2</div>
<div class='test'>Test 4</div>
<div class='test'>Test 5</div>
<div class='test'>Test 6</div>
<div class='test'>Test 7</div>
<div class='test'>Test 8</div>
</div>
<div class='wrap'>
<div class="header">Header 3</div>
<div class='test'>Test 9</div>
<div class='test'>Test 10</div>
<div class='test'>Test 11</div>
<div class='test'>Test 12</div>
</div>
<div class='wrap'>
<div class="header">Header 4</div>
<div class='test'>Test 13</div>
<div class='test'>Test 14</div>
</div>

Any ideas? 有任何想法吗? Thanks in advance. 提前致谢。

As of jQuery v1.4 you can use the nextUntil() method, allowing you to do something like this: 从jQuery v1.4开始,您可以使用nextUntil()方法,允许您执行以下操作:

var split_at = 'div.header';
$(split_at).each(function() {
  $(this).add($(this).nextUntil(split_at)).wrapAll("<div class='wrap'/>");
});

What you are asking to do is a terrible idea . 你要做的是一个可怕的想法 That's the kind of stuff you should do server-side. 那是你应该在服务器端做的事情。 (There are always exceptions). (总有例外)。

That being said, the following code should do what you ask. 话虽这么说,以下代码应该按照你的要求做。

$('.header').each(function() {
  var head = $(this);

  if(!head.parent().hasClass('wrap')) {
    head.before('div class="wrap"></div>');

    var wrap = head.prev();
    var curr = head;

    do {
      var currEl = curr;
      curr = curr.next();

      currEl.appendTo(wrap);
    } while(curr.length > 0 && !curr.hasClass('header'));
  }
});

NOTE: 注意:

I do not usually develop in jQuery, so sorry if I don't follow whatever the standard way of doing jQuery is. 我通常不用jQuery开发,很抱歉如果我不遵循jQuery的标准方式。

Here is another method. 这是另一种方法。 Not quite as pretty as Andrew's (EDIT: although I tried his and it's not working? I'm sure it's just some minor oversight) but does essentially the same thing: 不像安德鲁那样漂亮(编辑:虽然我尝试了他的并且它不起作用?我确定这只是一些小的疏忽)但基本上是相同的事情:

jQuery(function($){ 

  var $everything = $('.header,.test'); 
  var splitAtHeaders = []; 

  $everything.each(function(index){ 
    var $item = $(this); 
    if ('header'===$item.attr('className') || !splitAtHeaders.length) { 
      splitAtHeaders[splitAtHeaders.length] = []; 
    } 
    splitAtHeaders[splitAtHeaders.length-1].push($item); 
  }); 

  $.each(splitAtHeaders, function(){ 
    var currentWrapper = null; 
    $.each(this, function(index){ 
      if (0===index || !currentWrapper) { 
        currentWrapper = this.wrap('<div class="wrap"></div>'); 
      } 
      else { 
        currentWrapper.append(this); 
      } 
    }); 
  }); 

}); 

Here is a demo: http://jsbin.com/ojoqi/edit 这是一个演示: http//jsbin.com/ojoqi/edit

But I do agree that this is something that should be handled server-side if you can help it. 但我确实同意,如果你能提供帮助,这应该是服务器端处理的事情。

EDIT: I tried fixing Andrew's solution. 编辑:我试图修复安德鲁的解决方案。 Here's what I came up with: 这是我想出的:

$('.header').each(function() {
  var next = $(this).next();
  var head = $(this).wrap('<div class="wrap"></div>');
  while (next && next.hasClass('test')) {
    var curr = next;
    next = next.next();
    head.append(curr);
  }    
});

Assumption: Headers will have different text. 假设:标题会有不同的文字。 If not, use something else to distinguish the headers, like an id attribute. 如果没有,请使用其他内容来区分标头,例如id属性。

$("div.header").each(function() {
    var $header = $(this);

    var $tests = $.grep(
        $("div.test"),
        function(n) {
            return $(n).prevAll("div.header").text() == $header.text();
        });

    $.merge($header, $tests).wrapAll($("<div class='wrap'>"));
});

I'd do it like this: 我这样做:

var divs = $( 'div' );
var headers = divs.filter( '.header' );

if ( headers.length != 0 ) {
  var start = 0;
  var wrapper = $( '<div class="wrap" />' );

  headers.each( function() {
    var pos = divs.index( this );
    divs.slice( start, pos - 1 ).wrapAll( wrapper.clone() );
    start = pos;
  } );

  divs.slice( start ).wrapAll( wrapper.clone() );
}

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

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