Reputation: 177
I have a lot of divs having class line
with strong.datum
element within. I would need to highlight first and last element of each sequence with class .active
. If it is not possible to do it with CSS, is there any chance to do it via jQuery?
In this example should have class .start
elements .dt_26, .dt_66, .dt_27, .dt_77
and class .end
should have elements .dt_46, .dt_76, .dt_57 and .dt_97
.
<div class="line">
<strong class="dt_16 app_54 datum">1.6.</strong>
<strong class="dt_26 app_54 datum active">2.6.</strong>
<strong class="dt_36 app_54 datum active">3.6.</strong>
<strong class="dt_46 app_54 datum active">4.6.</strong>
<strong class="dt_56 app_54 datum">5.6.</strong>
<strong class="dt_66 app_54 datum active">6.6.</strong>
<strong class="dt_76 app_54 datum active">7.6.</strong>
<strong class="dt_86 app_54 datum active">8.6.</strong>
<strong class="dt_96 app_54 datum active">9.6.</strong>
<strong class="dt_106 app_54 datum">10.6.</strong>
</div>
<div class="line">
<strong class="dt_17 app_54 datum">1.7.</strong>
<strong class="dt_27 app_54 datum active">2.7.</strong>
<strong class="dt_37 app_54 datum active">3.7.</strong>
<strong class="dt_47 app_54 datum active">4.7.</strong>
<strong class="dt_57 app_54 datum active">5.7.</strong>
<strong class="dt_67 app_54 datum">6.7.</strong>
<strong class="dt_77 app_54 datum">7.7.</strong>
<strong class="dt_87 app_54 datum active">8.7.</strong>
<strong class="dt_97 app_54 datum active">9.7.</strong>
<strong class="dt_107 app_54 datum">10.7.</strong>
</div>
Upvotes: 0
Views: 164
Reputation: 33933
Here's a jQuery solution...
Using .prev()
and .next()
, you can loop through all the .line
.children()
elements and check if they're first or last.
I even made an addition for the fun of it... You also can check if they're "lonely"... ;)
As you can see, the code is pretty self explanatory...
$(".line").children().each(function(){
// Firsts
if( $(this).hasClass("active") && !$(this).prev().hasClass("active") ){
$(this).addClass("first");
}
// Lasts
if( $(this).hasClass("active") && !$(this).next().hasClass("active") ){
$(this).addClass("last");
}
// Lonelies
if( $(this).hasClass("active") && !$(this).prev().hasClass("active") && !$(this).next().hasClass("active") ){
$(this).removeClass("first last").addClass("alone");
}
});
.first{
color: green;
}
.last{
color: orange;
}
.alone{
color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="line">
<strong class="dt_16 app_54 datum">1.6.</strong>
<strong class="dt_26 app_54 datum active">2.6.</strong>
<strong class="dt_36 app_54 datum active">3.6.</strong>
<strong class="dt_46 app_54 datum active">4.6.</strong>
<strong class="dt_56 app_54 datum">5.6.</strong>
<strong class="dt_66 app_54 datum active">6.6.</strong>
<strong class="dt_76 app_54 datum active">7.6.</strong>
<strong class="dt_86 app_54 datum active">8.6.</strong>
<strong class="dt_96 app_54 datum active">9.6.</strong>
<strong class="dt_106 app_54 datum">10.6.</strong>
</div>
<div class="line">
<strong class="dt_17 app_54 datum">1.7.</strong>
<strong class="dt_27 app_54 datum active">2.7.</strong>
<strong class="dt_37 app_54 datum active">3.7.</strong>
<strong class="dt_47 app_54 datum active">4.7.</strong>
<strong class="dt_57 app_54 datum active">5.7.</strong>
<strong class="dt_67 app_54 datum">6.7.</strong>
<strong class="dt_77 app_54 datum">7.7.</strong>
<strong class="dt_87 app_54 datum active">8.7.</strong>
<strong class="dt_97 app_54 datum">9.7.</strong>
<strong class="dt_107 app_54 datum">10.7.</strong>
</div>
Upvotes: 1
Reputation: 42352
It's not exactly possible in CSS - so here is a vanilla JS solution - see explanations inline:
// get a list of line elemnts
[...document.querySelectorAll('.line')].forEach(function(line) {
// reduce the child elements
[...line.querySelectorAll('strong')].reduce(function(p,c) {
if (c.classList.contains('active')) {
if(!p) // mark first
c.classList.add('first');
// mark last after checking the following child
if((!c.nextElementSibling || !c.nextElementSibling.classList.contains('active')) && p)
c.classList.add('last');
return true;
}
return false;
}, false);
})
.first {
color: cadetblue;
}
.last {
color: red;
}
<div class="line">
<strong class="dt_16 app_54 datum">1.6.</strong>
<strong class="dt_26 app_54 datum active">2.6.</strong>
<strong class="dt_36 app_54 datum active">3.6.</strong>
<strong class="dt_46 app_54 datum active">4.6.</strong>
<strong class="dt_56 app_54 datum">5.6.</strong>
<strong class="dt_66 app_54 datum active">6.6.</strong>
<strong class="dt_76 app_54 datum active">7.6.</strong>
<strong class="dt_86 app_54 datum active">8.6.</strong>
<strong class="dt_96 app_54 datum active">9.6.</strong>
<strong class="dt_106 app_54 datum">10.6.</strong>
</div>
<div class="line">
<strong class="dt_17 app_54 datum">1.7.</strong>
<strong class="dt_27 app_54 datum active">2.7.</strong>
<strong class="dt_37 app_54 datum active">3.7.</strong>
<strong class="dt_47 app_54 datum active">4.7.</strong>
<strong class="dt_57 app_54 datum active">5.7.</strong>
<strong class="dt_67 app_54 datum">6.7.</strong>
<strong class="dt_77 app_54 datum">7.7.</strong>
<strong class="dt_87 app_54 datum active">8.7.</strong>
<strong class="dt_97 app_54 datum active">9.7.</strong>
<strong class="dt_107 app_54 datum">10.7.</strong>
</div>
Upvotes: 1
Reputation: 54628
AFAIK You can't select the first and last element with additional requirements (like with specific class etc) via css. Fairly easy with jQuery.
$(document).ready(function() {
$(".line").each(function(i, line) {
$(line).children("strong.active:first, strong.active:last").addClass("highlight");
});
});
.highlight {
background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="line">
<strong class="dt_16 app_54 datum">1.6.</strong>
<strong class="dt_26 app_54 datum active">2.6.</strong>
<strong class="dt_36 app_54 datum active">3.6.</strong>
<strong class="dt_46 app_54 datum active">4.6.</strong>
<strong class="dt_56 app_54 datum">5.6.</strong>
<strong class="dt_66 app_54 datum active">6.6.</strong>
<strong class="dt_76 app_54 datum active">7.6.</strong>
<strong class="dt_86 app_54 datum active">8.6.</strong>
<strong class="dt_96 app_54 datum active">9.6.</strong>
<strong class="dt_106 app_54 datum">10.6.</strong>
</div>
<div class="line">
<strong class="dt_17 app_54 datum">1.7.</strong>
<strong class="dt_27 app_54 datum active">2.7.</strong>
<strong class="dt_37 app_54 datum active">3.7.</strong>
<strong class="dt_47 app_54 datum active">4.7.</strong>
<strong class="dt_57 app_54 datum active">5.7.</strong>
<strong class="dt_67 app_54 datum">6.7.</strong>
<strong class="dt_77 app_54 datum">7.7.</strong>
<strong class="dt_87 app_54 datum active">8.7.</strong>
<strong class="dt_97 app_54 datum active">9.7.</strong>
<strong class="dt_107 app_54 datum">10.7.</strong>
</div>
The reason this works and something like:
.line > strong.active:first {
background-color: yellow;
}
doesn't work is because the jQuery parsing engine is not exactly the same as CSS selectors. :first in jQuery just selects the first element after selectors, where-as :first
is css literally means the first element regardless of selectors, so (CSS) if your selectors remove the literal-first element then :first
never matches.
Upvotes: 1