I've got a list of elements and I want to use the header divs to separate them after the pages loaded up. 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:
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.
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
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.
$("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() );
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.