Search code examples
jquerycssjquery-mobilenavbarhref

Active class in jQuery navbar doesn't work when I put an href


I don't get it, I made a navbar using jQuery mobile as explained on their website: https://demos.jquerymobile.com/1.4.5/navbar/

And it works fine when I don't put an href in the unordered list elements (the clicked items of the navbar become active):

<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>
<div id="menu">
  <div data-role="navbar">
    <ul>
      <li><a href="" class="contentUpdate" id="1"><i class="fas fa-swimmer"></i>Swim</a></li>
      <li><a href="" class="contentUpdate" id="2"><i class="fas fa-biking"></i>Cycle</a></li>
      <li><a href="" class="contentUpdate" id="3"><i class="fas fa-running"></i>Run</a></li>
    </ul>
  </div>
  <!-- /navbar -->

</div>

However, when I put a reference to another div in the href (I'm making a webpage that, when clicking the navbar item, the content changes) the active class is not activated anymore when clicking.

<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

<div id="menu">
  <div data-role="navbar">
    <ul>
      <li><a href="#swim" class="contentUpdate" id="1"><i class="fas fa-swimmer"></i>Swim</a></li>
      <li><a href="#cycle" class="contentUpdate" id="2"><i class="fas fa-biking"></i>Cycle</a></li>
      <li><a href="#run" class="contentUpdate" id="3"><i class="fas fa-running"></i>Run</a></li>
    </ul>
  </div>
  <!-- /navbar -->
</div>

I have tried adding a class to the items with jQuery, but it doesn't work. If I put the following code the first item does not become active when clicking:

$("#1").click(function() {
  $("#1").addClass("ui-btn-active");
});
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

<div id="menu">
  <div data-role="navbar">
    <ul>
      <li><a href="#swim" class="contentUpdate" id="1"><i class="fas fa-swimmer"></i>Swim</a></li>
      <li><a href="#cycle" class="contentUpdate" id="2"><i class="fas fa-biking"></i>Cycle</a></li>
      <li><a href="#run" class="contentUpdate" id="3"><i class="fas fa-running"></i>Run</a></li>
    </ul>
  </div>
  <!-- /navbar -->
</div>

However, I know it works because if I put the following code the other two items do change to the active class:

$("#1").click(function() {

  $("#1").addClass("ui-btn-active");
  $("#2").addClass("ui-btn-active");
  $("#3").addClass("ui-btn-active");

});
<link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.css" />
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.min.js"></script>

<div id="menu">
  <div data-role="navbar">
    <ul>
      <li><a href="#swim" class="contentUpdate" id="1"><i class="fas fa-swimmer"></i>Swim</a></li>
      <li><a href="#cycle" class="contentUpdate" id="2"><i class="fas fa-biking"></i>Cycle</a></li>
      <li><a href="#run" class="contentUpdate" id="3"><i class="fas fa-running"></i>Run</a></li>
    </ul>
  </div>
  <!-- /navbar -->
</div>

Does somebody know what is happening? I would really appreciate it if someone could help me My Navbar with an active class


Solution

  • Just only checking the navbar anchor click isn't enough. If You need a solution which also works with the back-button or by navigating in code, after transitions, and with an external toolbar, You may need to check the current page inside the pagecontainerchange trigger and update the navbar accordingly:

    $(function(){
      $( "[data-role='header'], [data-role='footer']" ).toolbar({ theme: "a" }).enhanceWithin();
    });
    
    $( document ).on( "pagecontainerchange", function(e, ui) {
      if(typeof ui.toPage == "object") {
        var id = $.mobile.activePage.attr("id"),
          navbar = $("[data-role=navbar]"),
          buttons = navbar.find(".ui-btn"),
          current = navbar.find("a[href='#"+id+"']");
        buttons.removeClass($.mobile.activeBtnClass);
        current.addClass($.mobile.activeBtnClass);
      }
    });
    <!DOCTYPE html>
    <html>
      <head>
        <title>Focus Tab</title>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
        <link rel="stylesheet" href="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.css" />
        <script src="https://code.jquery.com/jquery-2.2.4.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.js"></script>
      </head>
      <body>
        <div data-role="header">
          <div id="menu" data-role="navbar">
            <ul>
              <li><a href="#swim" id="1">Swim</a></li>
              <li><a href="#cycle" id="2">Cycle</a></li>
              <li><a href="#run" id="3">Run</a></li>
            </ul>
          </div>	
        </div>
        <div id="swim" data-role="page">
          <div data-role="content">Page Swim </div>
        </div>
        <div id="cycle" data-role="page">
          <div data-role="header" data-add-back-btn="true">
            <h3>My app</h3>
          </div>
          <div data-role="content">Page cycle</div>
        </div>
        <div id="run" data-role="page">
          <div data-role="content">Page run</div>
        </div>
      </body>
    </html>