Reputation: 553
I'm trying to wrap each two elements close to each other containing the classes black
and blue
in a <div class="wrap">
across my page.
I tried this, but it doesn't work as I need:
$(".black, .blue").each(function() {
$(this).next().hasClass('black').wrapAll('<div class="wrap"></div>')
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col red"></div>
<div class="col black"></div>
<div class="col blue"></div>
<div class="col red"></div>
<div class="col white"></div>
<div class="col yellow"></div>
<div class="col red"></div>
<div class="col black"></div>
<div class="col bllue"></div>
This is my desired output:
<div class="col red"></div>
<div class="wrap">
<div class="col black"></div>
<div class="col blue"></div>
</div>
<div class="col red"></div>
<div class="col white"></div>
<div class="col yellow"></div>
<div class="col red"></div>
<div class="wrap">
<div class="col black"></div>
<div class="col blue"></div>
</div>
Upvotes: 1
Views: 134
Reputation: 337560
Your current approach is flawed as you loop over both the .black
and .blue
elements, only try to detect following .black
elements, and also because you use hasClass()
, which returns a boolean value, yet try to then call a method on it.
To achieve this you can loop over every .black
and determine if the next()
element is .blue
. If it is you can wrap them both in a div
, like this:
$('.black').each(function() {
var $this = $(this);
var $next = $this.next();
if ($next.is('.blue'))
$this.add($next).wrapAll('<div class="wrap"></div>');
});
.red { color: red; }
.black { color: black; }
.blue { color: blue; }
.white { color: white; }
.yellow { color: yellow; }
.wrap {
border: 1px dotted #CCC;
background-color: #EEE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col red">Foo</div>
<div class="col black">Foo</div>
<div class="col blue">Foo</div>
<div class="col red">Foo</div>
<div class="col white">Foo</div>
<div class="col yellow">Foo</div>
<div class="col red">Foo</div>
<div class="col black">Foo</div>
<div class="col blue">Foo</div>
Using your example I would like to add a third element having the same class blue.
I assume in this scenario that there may be an unlimited number of .blue
elements after the .black
, and they should all be wrapped. In that case use nextUntil()
along with :not(.blue)
, like this:
$('.black').each(function() {
var $this = $(this);
if ($this.next().is('.blue')) {
$this.add($this.nextUntil(':not(.blue)')).wrapAll('<div class="wrap"></div>');
}
});
.red { color: red; }
.black { color: black; }
.blue { color: blue; }
.white { color: white; }
.yellow { color: yellow; }
.wrap {
border: 1px dotted #CCC;
background-color: #EEE;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col red">Foo</div>
<div class="col black">Foo</div>
<div class="col blue">Foo</div>
<div class="col red">Foo</div>
<div class="col white">Foo</div>
<div class="col yellow">Foo</div>
<div class="col red">Foo</div>
<div class="col black">Foo</div>
<div class="col blue">Foo</div>
<div class="col blue">Foo</div>
<div class="col blue">Foo</div>
<div class="col red">Foo</div>
Upvotes: 2
Reputation: 20039
Use +
Next Adjacent Selector (“prev + next”)
$(".black + .blue").each(function() {
$(this).prev().addBack().wrapAll('<div class="wrap"></div>')
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="col red"></div>
<div class="col black"></div>
<div class="col blue"></div>
<div class="col red"></div>
<div class="col white"></div>
<div class="col yellow"></div>
<div class="col red"></div>
<div class="col black"></div>
<div class="col blue"></div>
Upvotes: 2