Javascript 使用jQuery环绕元素组

Javascript 使用jQuery环绕元素组,javascript,jquery,html,css,dom,Javascript,Jquery,Html,Css,Dom,我有一个元素列表,我想在页面加载后使用header div来分隔它们。下面的代码 <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

我有一个元素列表,我想在页面加载后使用header div来分隔它们。下面的代码

<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>
标题1
测试1
测试2
测试3
标题2
测试4
测试5
测试6
测试7
测试8
标题3
测试9
测试10
测试11
测试12
标题4
测试13
测试14
会变成,

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

标题1
测试1
测试2
测试3
标题2
测试4
测试5
测试6
测试7
测试8
标题3
测试9
测试10
测试11
测试12
标题4
测试13
测试14

有什么想法吗?提前谢谢。

你要求做的是一个糟糕的主意。这是你应该在服务器端做的事情。(总是有例外)

也就是说,下面的代码应该满足您的要求

$('.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'));
  }
});
$('.header')。每个(函数(){
var head=$(本);
如果(!head.parent().hasClass('wrap')){
头.前('div class=“wrap”>);
var wrap=head.prev();
var curr=水头;
做{
var currEl=curr;
curr=curr.next();
货币附加物(包装);
}而(curr.length>0&!curr.hasglass('header');
}
});
注意:


我通常不使用jQuery进行开发,因此如果我没有遵循执行jQuery的标准方法,那么很抱歉。

这里是另一种方法。没有安德鲁的漂亮(编辑:虽然我试过他的,但不起作用?我肯定这只是一些小疏忽),但本质上是一样的:

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

}); 
jQuery(函数($){
变量$everything=$('.header.test');
var splitAtHeaders=[];
$everything.each(函数(索引){
变量$item=$(此项);
if('header'==$item.attr('className')| |!splitAtHeaders.length){
SplitaHeaders[SplitaHeaders.length]=[];
} 
splitAtHeaders[splitAtHeaders.length-1]。推送($item);
}); 
$.each(拆分器、函数(){
var currentWrapper=null;
$.each(此函数,函数(索引){
如果(0==索引| |!currentWrapper){
currentWrapper=this.wrap(“”);
} 
否则{
currentWrapper.append(这个);
} 
}); 
}); 
}); 
下面是一个演示:

但我确实同意,如果您可以帮助的话,这应该在服务器端处理

编辑:我试着修正安德鲁的解决方案。以下是我的想法:

$('.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);
  }    
});
$('.header')。每个(函数(){
var next=$(this.next();
var head=$(this.wrap(“”);
while(next&&next.hasClass('test')){
var curr=下一个;
next=next.next();
头.附加(货币);
}    
});

假设:标题将有不同的文本。如果不是,则使用其他方法来区分标题,如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'>"));
});
$(“div.header”)。每个(函数(){
var$头=$(此);
var$tests=$.grep(
$(“分区测试”),
函数(n){
返回$(n).prevAll(“div.header”).text()==$header.text();
});
$.merge($header,$tests).wrapAll($(“”);
});
我会这样做:

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() );
}
var split_at = 'div.header';
$(split_at).each(function() {
  $(this).add($(this).nextUntil(split_at)).wrapAll("<div class='wrap'/>");
});
var divs=$('div');
var headers=divs.filter('.header');
if(headers.length!=0){
var start=0;
var包装器=$('');
headers.each(函数(){
var pos=分类指数(本);
slice(start,pos-1).wrapAll(wrapper.clone());
开始=位置;
} );
divs.slice(start.wrapAll(wrapper.clone());
}

从jQuery v1.4开始,您可以使用该方法,允许您执行以下操作:

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() );
}
var split_at = 'div.header';
$(split_at).each(function() {
  $(this).add($(this).nextUntil(split_at)).wrapAll("<div class='wrap'/>");
});
var split_at='div.header';
$(拆分处)。每个(函数(){
$(this).add($(this).nextUntil(split_at)).wrapAll(“”);
});

实际上,只需使用

即可!这不是一个很好的主意,这里没有理由使用jQuery。即使您使用它,我建议将它改为notheader而不是while.hasClass('test')。。。标题之间的元素不一定都有相同的类(在本例中是这样的,但谁知道真正的代码是怎么说的)在客户端完全进行这种HTML转换并不少见,比如说,在一个丰富的HTML编辑框中。也许这并不总是一个好主意,但是可以形成为选项卡式交互动态创建选项卡组的基础。在这个特殊的(Edge?)案例中,我不认为这是一个可怕的想法,如果文本被输入在一个富文本编辑器中?我不能告诉我的用户在标题下为内容包装div,所以实际上有一些用例。尽管@Fracty的答案对我来说似乎更好。我喜欢这个修复。你给出的函数是一个选择器,当调用next()并且没有下一个元素时,它会“环绕”。