2009-08-01 108 views
3

我有一個元素列表,我想在頁面加載後使用標題div將它們分開。所以,下面的代碼,使用jQuery來環繞元素組

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

任何想法?提前致謝。

回答

4

你要做的是一個可怕的想法。這是你應該在服務器端做的事情。 (總是有例外)。

這就是說,下面的代碼應該做你所要求的。

$('.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的標準方式是。

+1

同意!不是一個好主意,在這裏沒有理由使用jQuery。 – doomspork 2009-08-01 23:02:59

+0

即使你走低谷與此,我會建議改變它不頭,而不是while.hasClass('測試')... 標頭之間的元素並不是必須的都具有相同的類(他們在這個例子,但誰知道真正的代碼說什麼) – Sander 2009-08-02 00:41:18

+0

哦,如果頭是實際創建serverside,那麼我確實會在服務器端做包裝div。 但你可以有一個員工畫廊頁面 ,當你點擊一個過濾器按鈕的排序,按辦公室位置分組他們可以動態地將所有的人員從辦公室1添加到包裝(與頭div添加)和從辦公室2人到包裝等... 但問題的方式,讓我覺得頭是印在服務器端,所以我會覺得奇怪不做包裝服務器端太。 – Sander 2009-08-02 00:47:35

2

這是另一種方法。不是很漂亮,安德魯(編輯:雖然我盡了,它不是工作,我敢肯定,這只是一些小的疏忽),但本質上是做同樣的事情:

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

假設:標題將有不同的文字。如果不是,請使用其他名稱來區分標題,如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'>")); 
}); 
0

我會做這樣的:

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

在jQuery 1.4版的可以用nextUntil()方法,讓你做這樣的事情:

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