Reputation: 538
I'm trying to create a tab functionality in jQuery.
My HTML code looks like this:
<div class="feature__content">
<h3 class="feature__content__toptitle"><?php the_sub_field('feature_top_title'); ?></h3>
<h2 class="feature__content__title"><?php the_sub_field('feature_title'); ?></h2>
<div class="feature__content__tabs">
<span class="feature__content__tabs__selector" data-selector="overview">Overview</span>
<span class="feature__content__tabs__selector" data-selector="features">Features</span>
</div>
<div class="feature__content__target" data-target="overview">
<?php the_sub_field('feature_overview'); ?>
</div>
<div class="feature__content__target" data-target="features">
features slider here
</div>
</div>
When I click on the span with data-selector="overview"
, the div with data-target="overview"
must be shown. And when I click on features, the features target must be shown.
I honestly don't know how to go a few levels up and then select a specific with with a data-attribute.
My jQuery code already looks like this:
jQuery('.feature__content__target:last-child()').hide();
jQuery('.feature__content__tabs__selector').on('click', function(e) {
var selector = jQuery(this).data('selector');
var targets = jQuery('feature__content__target');
var container = jQuery(this).closest('.feature__content');
var target = container.find('div[data-target="' + selector + '"]');
console.log(selector);
targets.removeClass('show');
target.addClass('show');
});
Upvotes: 1
Views: 1018
Reputation: 370879
Use .closest
to navigate to the nearest ancestor of the target which has the .feature__content
class, and from that, .find
the element with the matching data-target
:
jQuery('.feature__content__tabs__selector').on('click', function(e) {
var selector = jQuery(this).data('selector');
var container = $(this).closest('.feature__content');
var target = container.find('div[data-target="' + selector + '"]')
target.toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="feature__content">
<h3 class="feature__content__toptitle">
<?php the_sub_field('feature_top_title'); ?>
</h3>
<h2 class="feature__content__title">
<?php the_sub_field('feature_title'); ?>
</h2>
<div class="feature__content__tabs">
<span class="feature__content__tabs__selector" data-selector="overview">Overview</span>
<span class="feature__content__tabs__selector" data-selector="features">Features</span>
</div>
<div class="feature__content__overview" data-target="overview">
feature overview
</div>
<div class="feature__content__features" data-target="features">
features slider here
</div>
</div>
Or, of course, you could call .parent()
twice instead of using closest
:
jQuery('.feature__content__tabs__selector').on('click', function(e) {
var selector = jQuery(this).data('selector');
var container = $(this).parent().parent();
var target = container.find('div[data-target="' + selector + '"]')
target.toggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="feature__content">
<h3 class="feature__content__toptitle">
<?php the_sub_field('feature_top_title'); ?>
</h3>
<h2 class="feature__content__title">
<?php the_sub_field('feature_title'); ?>
</h2>
<div class="feature__content__tabs">
<span class="feature__content__tabs__selector" data-selector="overview">Overview</span>
<span class="feature__content__tabs__selector" data-selector="features">Features</span>
</div>
<div class="feature__content__overview" data-target="overview">
feature overview
</div>
<div class="feature__content__features" data-target="features">
features slider here
</div>
</div>
Or, with your new HTML, if you want to toggle with classes instead, then just use those classes, and not .show()
/ .hide()
(an element toggled with those methods will not be affected by classes that make an element visible or not).
Note that you need to use .
before a class to indicate that you want to search for an element with that class. (Your var targets = jQuery('feature__content__target');
will look for elements with a tag name of feature__content__target
)
jQuery('.feature__content__tabs__selector').on('click', function(e) {
var selector = jQuery(this).data('selector');
var targets = jQuery('.feature__content__target');
var container = jQuery(this).closest('.feature__content');
var target = container.find('div[data-target="' + selector + '"]');
console.log(selector);
targets.removeClass('show');
target.addClass('show');
});
.feature__content__target {
display: none;
}
.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="feature__content">
<h3 class="feature__content__toptitle">
<?php the_sub_field('feature_top_title'); ?>
</h3>
<h2 class="feature__content__title">
<?php the_sub_field('feature_title'); ?>
</h2>
<div class="feature__content__tabs">
<span class="feature__content__tabs__selector" data-selector="overview">Overview</span>
<span class="feature__content__tabs__selector" data-selector="features">Features</span>
</div>
<div class="feature__content__target" data-target="overview">
feature overview here
</div>
<div class="feature__content__target" data-target="features">
features slider here
</div>
</div>
Upvotes: 2
Reputation: 68943
You can use .closest()
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
and find()
Get the descendants of each element in the current set of matched elements, filtered by a selector, jQuery object, or element.
jQuery('.feature__content__tabs__selector').on('click', function(e){
e.preventDefault();
var selector = jQuery(this).data('selector');
jQuery(this).closest('.feature__content').find('div[data-target="'+ selector +'"]').toggle();
});
[data-selector="overview"]{
color: green;
}
[data-selector="features"]{
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="feature__content">
<h3 class="feature__content__toptitle"><?php the_sub_field('feature_top_title'); ?></h3>
<h2 class="feature__content__title"><?php the_sub_field('feature_title'); ?></h2>
<div class="feature__content__tabs">
<span class="feature__content__tabs__selector" data-selector="overview">Overview</span>
<span class="feature__content__tabs__selector" data-selector="features">Features</span>
</div>
<div class="feature__content__overview" data-target="overview">
overview here
</div>
<div class="feature__content__features" data-target="features">
features slider here
</div>
</div>
Upvotes: 1