I’m working with a BE dev on a site – they’ve built it in Umbraco with dynamic blocks for each section of content that can be added to the pages.
Our client is trying to add the same ‘tabbed content’ block twice on one page but the second block doesn’t work as the JS is just targeting the first element it finds with the classes
Is there a way I can modify the JS to allow both blocks to work independently? Here is a simplified demo:
$('section.tabs nav li').click(function(){
var tabIndex = $(this).index();
$(this).addClass('active').siblings().removeClass('active');
$('section.tabs ul.tabs li.tab').eq(tabIndex).addClass('active').siblings().removeClass('active');
});
section.tabs main.tabsContainer ul.tabs li.tab{
display:none;
}
section.tabs main.tabsContainer ul.tabs li.tab.active{
display:flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>
First Tabbed Section
</h1>
<section class="tabs">
<nav>
<ul>
<li class="active">
<button>
Click for Tab 1
</button>
</li>
<li>
<button>
Click for Tab 2
</button>
</li>
<li>
<button>
Click for Tab 3
</button>
</li>
</ul>
</nav>
<main class="tabsContainer">
<ul class="tabs">
<li class="tab active">
<h2>
Tab 1
</h2>
</li>
<li class="tab">
<h2>
Tab 2
</h2>
</li>
<li class="tab">
<h2>
Tab 3
</h2>
</li>
</ul>
</main>
</section>
<hr />
<h1>
Second Tabbed Section
</h1>
<section class="tabs">
<nav>
<ul>
<li class="active">
<button>
Click for Tab 1
</button>
</li>
<li>
<button>
Click for Tab 2
</button>
</li>
<li>
<button>
Click for Tab 3
</button>
</li>
</ul>
</nav>
<main class="tabsContainer">
<ul class="tabs">
<li class="tab active">
<h2>
Tab 1
</h2>
</li>
<li class="tab">
<h2>
Tab 2
</h2>
</li>
<li class="tab">
<h2>
Tab 3
</h2>
</li>
</ul>
</main>
</section>
3
Answers
The selector
$("section.tabs nav li")
works with every corresponding element it finds in your page, so if you have 2, they both should work.If it’s not, maybe there is another problem.
If you run
$('section.tabs nav li')
on the console, do you see just one or both?Another thing, how do you distinct the clicked tab element in
$('section.tabs ul.tabs li.tab').eq(tabIndex)
?This looks like a case where DOM traversal can be handy. Take a look at what this is selecting:
This is from the context of the entire DOM, so any matching element(s) within the entire DOM are returned. Alternatively, if you start from the context of
this
, you can traverse upward to a common parent and then find the target element(s) within the context of only that parent. For example:The selector
$('section.tabs ul.tabs li.tab')
works across both tabs – so$('section.tabs ul.tabs li.tab').length
(in your fiddle) will be6
, not3
.When you click second-section tab2, its index is 1 (0-based).
This corresponds to
$('section.tabs ul.tabs li.tab').eq(4)
To only apply to the current section, use relative DOM navigation – ie navigate up from the current element rather than down from the top-level document:
Updated simplified example snippet: