Используйте jQuery, чтобы обернуть вокруг группы элементов - PullRequest
3 голосов
/ 02 августа 2009

У меня есть список элементов, и я хочу использовать 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>

станет,

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

Есть идеи? Заранее спасибо.

Ответы [ 6 ]

8 голосов
/ 11 ноября 2010

Начиная с jQuery v1.4, вы можете использовать метод nextUntil(), позволяющий сделать что-то вроде этого:

var split_at = 'div.header';
$(split_at).each(function() {
  $(this).add($(this).nextUntil(split_at)).wrapAll("<div class='wrap'/>");
});
4 голосов
/ 02 августа 2009

То, что вы просите сделать, это ужасная идея . Это то, что вы должны делать на стороне сервера. (Всегда есть исключения).

При этом следующий код должен делать то, что вы просите.

$('.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'));
  }
});

Примечание:

Обычно я не разрабатываю в jQuery, поэтому извините, если я не следую стандартному способу выполнения jQuery.

2 голосов
/ 02 августа 2009

Вот еще один метод. Не совсем так, как у Эндрю (РЕДАКТИРОВАТЬ: хотя я пробовал его, и он не работает? Я уверен, что это всего лишь небольшой надзор), но делает по сути то же самое:

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

}); 

Вот демоверсия: http://jsbin.com/ojoqi/edit

Но я согласен, что это то, что должно обрабатываться на стороне сервера, если вы можете помочь.

РЕДАКТИРОВАТЬ: я пытался исправить решение Эндрю. Вот что я придумал:

$('.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);
  }    
});
0 голосов
/ 10 мая 2011

На самом деле, просто используйте http://jquery.kidsil.net/next-and-prev-wrap/

0 голосов
/ 02 августа 2009

Я бы сделал это так:

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() );
}
0 голосов
/ 02 августа 2009

Предположение: заголовки будут иметь другой текст. Если нет, используйте что-то другое, чтобы различать заголовки, например атрибут 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'>"));
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...