I have an amount of div elements, i would like to target a specific number of the closet elements, in this case the closest 2 either side of itself and add a class.
$(document).ready(function() {
var dot = $('.dot3');
if (dot.length > 5) {
var activeDot = $('.dot3.active');
var closestDots = $(activeDot).siblings(3);
$(closestDots).css('background-color', '#ff0000');
$(activeDot).css('background-color', '#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
CodePudding user response:
To do what you require you can use prevAll()
/nextAll()
to get the preceding/following dot elements, then slice()
to limit the selection to the 2 nearest in each direction. Then you can apply a CSS class to them to add the required syling.
$(document).ready(function() {
let $dots = $('.dot3');
if ($dots.length > 5) {
var $activeDot = $('.dot3.active');
let $prev2 = $activeDot.prevAll().slice(0, 2);
let $next2 = $activeDot.nextAll().slice(0, 2);
$prev2.add($next2).addClass('active');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
.dot3.active {
background-color: #F00;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
<div ></div>
CodePudding user response:
To get the elements on either side of the target element you could use the .next()
and .prev()
methods:
$(document).ready(function() {
var dot = $('.dot3');
if (dot.length > 5) {
var activeDot = $('.dot3.active');
var closestDots = $() // use add to make a collection
.add(activeDot.prev())
.add(activeDot.next());
$(closestDots).css('background-color', '#ff0000');
$(activeDot).css('background-color', '#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
Since the active dot and its siblings are all getting the same treatment, you could arguably keep things clearer by combining them all into a single collection before altering the CSS:
$(document).ready(function() {
var dot = $('.dot3');
if (dot.length > 5) {
var activeDot = $('.dot3.active');
var targetElements = $() // use add to make a collection
.add(activeDot)
.add(activeDot.prev())
.add(activeDot.next());
$(targetElements).css('background-color', '#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
If you need to support an arbitrary number of previous and next siblings, you can define your own methods called nextN
and prevN
that take an integer-- this is a rudimentary start without any error handling or checking for out of bounds:
$.fn.nextN = function (n) {
let newCollection = $();
let cachedElement = this;
for (let i = 0; i < n; i = 1) {
const nextElement = cachedElement.next();
newCollection = newCollection.add(nextElement);
cachedElement = nextElement;
}
return newCollection;
}
$.fn.prevN = function (n) {
let newCollection = $();
let cachedElement = this;
for (let i = 0; i < n; i = 1) {
const nextElement = cachedElement.prev();
newCollection = newCollection.add(nextElement);
cachedElement = nextElement;
}
return newCollection;
}
$(document).ready(function() {
var dot = $('.dot3');
if (dot.length > 5) {
var activeDot = $('.dot3.active');
var prevElements = activeDot.prevN(2);
var nextElements = activeDot.nextN(2);
$(activeDot).css('background-color', '#ff0000');
$(prevElements).css('background-color', '#ff0000');
$(nextElements).css('background-color', '#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
UPDATE based on Rory's answer, I have improved the helper methods to take advantage of nextAll()
and prevAll()
in lieu of looping:
$.fn.nextN = function (n) {
return this.nextAll().slice(0, n);
}
$.fn.prevN = function (n) {
return this.prevAll().slice(0, n);
}
$(document).ready(function() {
var dot = $('.dot3');
if (dot.length > 5) {
var activeDot = $('.dot3.active');
var prevElements = activeDot.prevN(2);
var nextElements = activeDot.nextN(2);
$(activeDot).css('background-color', '#ff0000');
$(prevElements).css('background-color', '#ff0000');
$(nextElements).css('background-color', '#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
CodePudding user response:
$( document ).ready(function() {
var dot = $('.dot3');
if( dot.length > 5 ) {
var activeDot = $('.dot3.active');
var $active = activeDot.filter('.active');
var $prev = $active.prev();
activeDot.removeClass('prev_slide').removeClass('next_slide');
if (!$prev.length) {
$prev = activeDot.last();
}else{
$prev.addClass('prev_div')
$active.prev().prev().addClass('prev_div')
}
var $next = $active.next();
if (!$next.length) {
$next = activeDot.first();
}else{
$next.addClass('next_div')
$active.next().next().addClass('next_div')
}
$('.next_div, .prev_div').css('background-color','#ff0000');
$(activeDot).css('background-color','#ff0000');
}
});
.dot3 {
background-color: #000;
height: 10px;
width: 10px;
border-radius: 100%;
display: inline-block;
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
<div >
</div>
You can use the below jquery to add before and after class which is active div.
$( document ).ready(function() {
var dot = $('.dot3');
if( dot.length > 5 ) {
var activeDot = $('.dot3.active');
var $active = activeDot.filter('.active');
var $prev = $active.prev();
activeDot.removeClass('prev_slide').removeClass('next_slide');
if (!$prev.length) {
$prev = activeDot.last();
}else{
$prev.addClass('prev_div')
$active.prev().prev().addClass('prev_div')
}
var $next = $active.next();
if (!$next.length) {
$next = activeDot.first();
}else{
$next.addClass('next_div')
$active.next().next().addClass('next_div')
}
$('.next_div, .prev_div').css('background-color','#ff0000');
$(activeDot).css('background-color','#ff0000');
}
});