Hopefully this one doesn't go off the beaten track too much - but I was wondering what the quickest method is in jQuery for targeting another element (that is a close relative of $(this).whatever
) with the same data id attribute. I currently have the following markup (if you use the latest Bootstrap you'll notice that this is just a simple card with nav headings):
<div class="card text-center">
<div class="card-header pb-0">
<ul id="contactGroups" class="nav justify-content-center nav-tabs card-header-tabs">
<li class="nav-item" data-id="1">
<a class="nav-link active" href="#">Contact Us</a>
</li>
<li class="nav-item" data-id="2">
<a class="nav-link" href="#">Business Enquiries</a>
</li>
<li class="nav-item" data-id="3">
<a class="nav-link" href="#">Follow Us</a>
</li>
</ul>
</div>
<div class="card-body active" data-id="1">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
<div class="card-body hidden" data-id="2">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
<div class="card-body hidden" data-id="3">
<h5 class="card-title">Special title treatment</h5>
<p class="card-text">With supporting text below as a natural lead-in to additional content.</p>
<a href="#" class="btn btn-primary">Go somewhere</a>
</div>
</div>
As you can see in the above markup I have data-id attributes added to the list elements - I want to then go in and find it's corresponding data-id (the ones with the card-body active or card-body hidden) so I can begin to play with them. However (!!) I don't want to select on some arbitary #id or .class that I assign. How would I go about doing this?
My jQuery thus far is as follows (however, this only flips the current class from non-active (or no class) to the active class giving the tab swop illusion:
$('#contactGroups').each(function(){
$(this).find('li').each(function(){
$(this).on('click', function() {
$('#contactGroups').find('.active').removeClass('active');
$(this).find('a').addClass('active');
})
});
});
Any thoughts would be greatly appreciated.
I can't quite make out whether you
Want to find the div
with the same data-id
as the li
, or
Want to find other li
s that are siblings ("brothers" + "sisters" = "siblings") of the li
that was clicked which also have data-id
attributes.
In the click handler on the li
, this
will refer to the li
that was clicked (it or its descendant a
element). With that in mind:
You can get the data-id
of that element using attr
:
var theId = `$(this).attr("data-id");
(Don't use data("id")
unless you need the features data
provides; more here .)
You can find elements within a given container using find
, or siblings via siblings
. So starting from the clicked li
, you can either do .closest(".card-header").siblings(...)
to access the header's siblings, or .closest(".card").find(...)
to search all through the containing .card
. The former is more specific, but more fragile; the latter is more robust if your structure changes a bit. Neither matters in terms of performance.
So I'd probably go up to .card
and use find
with a tag and attribute selector combination:
$(this).closest(".card").find("div[data-id='" + theId + "']")...
FWIW, there's no need to hook click
on each individual li
. Just use event delegation:
$("#contactGroups").on("click", "li[data-id]", function() {
var theId = $(this).attr("data-id");
var div = $(this).closest(".card").find("div[data-id='" + theId + "']");
// ...
});
Use $(this).siblings("[data-id]")
in the li
click handler to find all of its siblings with a data-id
(with any value).
...based on your comments:
$("#contactGroups").on("click", "li[data-id]", function() { var theId = $(this).attr("data-id"); var div = $(this).closest(".card").find("div[data-id='" + theId + "']"); div.removeClass("hidden").addClass("active"); div.siblings("[data-id]").removeClass("active").addClass("hidden"); });
.hidden { display: none; } .active { font-weight: bold; }
<div class="card text-center"> <div class="card-header pb-0"> <ul id="contactGroups" class="nav justify-content-center nav-tabs card-header-tabs"> <li class="nav-item" data-id="1"> <a class="nav-link active" href="#">Contact Us</a> </li> <li class="nav-item" data-id="2"> <a class="nav-link" href="#">Business Enquiries</a> </li> <li class="nav-item" data-id="3"> <a class="nav-link" href="#">Follow Us</a> </li> </ul> </div> <div class="card-body active" data-id="1"> <h5 class="card-title">(1) Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> <div class="card-body hidden" data-id="2"> <h5 class="card-title">(2) Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> <div class="card-body hidden" data-id="3"> <h5 class="card-title">(3) Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> </div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
each
because you have only one contactGroups
. data
function from jQuery. closest
function you can get the ancestor of li
elements. toggleClass
function to add or remove the class active
. $('div[data-id="${id}"]')
to find the related li
's div
. $('#contactGroups li').on('click'), ...);
$('#contactGroups li').on('click', function() { $(this).closest('#contactGroups').find('.active').toggleClass('active'); $(this).children('a').toggleClass('active'); $('div.card-body.active').toggleClass('active'); let id = $(this).data('id'); $(`div[data-id="${id}"]`).toggleClass('active'); });
.active { color: green !important; background-color: lightgreen; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="card text-center"> <div class="card-header pb-0"> <ul id="contactGroups" class="nav justify-content-center nav-tabs card-header-tabs"> <li class="nav-item" data-id="1"> <a class="nav-link active" href="#">Contact Us</a> </li> <li class="nav-item" data-id="2"> <a class="nav-link" href="#">Business Enquiries</a> </li> <li class="nav-item" data-id="3"> <a class="nav-link" href="#">Follow Us</a> </li> </ul> </div> <div class="card-body active" data-id="1"> <h5 class="card-title">Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> <div class="card-body hidden" data-id="2"> <h5 class="card-title">Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> <div class="card-body hidden" data-id="3"> <h5 class="card-title">Special title treatment</h5> <p class="card-text">With supporting text below as a natural lead-in to additional content.</p> <a href="#" class="btn btn-primary">Go somewhere</a> </div> </div>
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.