skip to Main Content

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


  1. 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) ?

    Login or Signup to reply.
  2. This looks like a case where DOM traversal can be handy. Take a look at what this is selecting:

    $('section.tabs ul.tabs li.tab')
    

    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:

    $(this).closest('section.tabs').find('ul.tabs li.tab')
    
    Login or Signup to reply.
  3. The selector $('section.tabs ul.tabs li.tab') works across both tabs – so $('section.tabs ul.tabs li.tab').length (in your fiddle) will be 6, not 3.

    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:

    $(this).closest("section.tabs").find("ul.tabs li.tab").eq(index)...
    

    Updated simplified example snippet:

    $('section.tabs nav li').click(function(){
        var tabIndex = $(this).index();
        $(this).addClass('active').siblings().removeClass('active');
    
        $(this).closest('section.tabs').find('ul.tabs li.tab').eq(tabIndex).addClass('active').siblings().removeClass('active');
    });
    li.tab {
      display: none;
    }
    
    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>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search