javascriptjqueryhreffragment-identifierlocation-href

Selecting the anchor tag of a particular href using jQuery


THE AIM

After refreshing the browser, I would like that the user stays in the menu/content they were before refreshing.

THE PROBLEM

After refreshing the browser, the content of the particular menu in which the user was before refreshing is shown as active (i.e. it is shown on the screen). However, the menu icon of that particular content is NOT shown as active (i.e. it does not show a black colour).

I am struggling in selecting the anchor element (where the icon is found) of the current href (the one the user was in before refreshing which is the same after refreshing).

THE ATTEMPT

$(document).ready(function() {

        $('a[class^=menu]').click(function() {
          $('a[class^=menu]').removeClass('active');
          $('div[class^=content]').removeClass('active');

          if($(this).hasClass('menu-1')) {
            $('.menu-1').addClass('active');
            $('.content-1').addClass('active');
          }

          if($(this).hasClass('menu-2')) {
            $('.menu-2').addClass('active');
            $('.content-2').addClass('active');
          }

          if($(this).hasClass('menu-3')) {
            $('.menu-3').addClass('active');
            $('.content-3').addClass('active');
          }
        });

        if (window.location.hash.substr(1) != '') {
          $('a[class^=menu],div[class^=content]').removeClass('active');

          // making the content active
          $('#' + window.location.hash.substr(1)).addClass('active');

          // making the menu active
          $('a[href="' + window.location.hash.substr(1) + '"]').addClass("active");

        }

      });
    .container {
      margin: 0 auto;
      background-color: #eee;
      border: 1px solid lightgrey;
      width: 20vw;
      height: 90vh;
      font-family: sans-serif;
      position: relative;
    }

    header {
      background-color: lightgreen;
      padding: 5px;
      text-align: center;
      text-transform: uppercase;
    }

    .bottom-navbar {
      position: absolute;
      bottom: 0;
      width: 100%;
      padding: 6px 0;
      overflow: hidden;
      background-color: lightgreen;
      border-top: 1px solid var(--color-grey-dark-3);
      z-index: 50;
      display: flex;
      justify-content: space-between;
    }

    .bottom-navbar>a {
      display: block;
      color: green;
      text-align: center;
      text-decoration: none;
      font-size: 20px;
      padding: 0 10px;
    }

    .bottom-navbar>a.active {
      color: black;
    }

    .menu-1.active,
    .menu-2.active,
    .menu-3.active {
      color: black;
    }

    .content-1,
    .content-2,
    .content-3 {
      display: none;
    }

    .content-1.active,
    .content-2.active,
    .content-3.active {
      display: block;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateX(-50%) translateY(-50%);
    }
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

 
 <div class="container">
    <header>My header</header>
    <div class="main-content">
      <div class="content-1 active" id="firstPage">House content</div>
      <div class="content-2" id="secondPage">Map content</div>
      <div class="content-3" id="thirdPage">Explore content</div>
      <div class="bottom-navbar">
        <a href="mywebsite#firstPage" class="menu-1 active"><i class="fa fa-home"></i></a>
        <a href="mywebsite#secondPage" class="menu-2"><i class="fa fa-map"></i></a>
        <a href="mywebsite#thirdPage" class="menu-3"><i class="fa fa-search"></i></a>
      </div>
    </div>
 </div>

Thanks for your help and suggestions.


Solution

  • the problem that you had was that your were looking for the wrong href.

    you were trying to find a[href="secondPage"] but it should be a[href="mywebsite#secondPage"]

    also I changed the way you were selecting the classes and adding them to be active. this way is more dynamic.

    note: in the JS file, there is a variable called hash, now it points to be #secondPage in order to fake that we are on the second page, you can change the value, re run it and it will pick a new active item. you just need to replace hash to be window.location.hash, also I took it out to a variable so you don't call it every time.

    // just replace this with "window.location.hash"
    const hash = "#secondPage";
    $(document).ready(function() {
    
      $('a[class^=menu]').click(function() {
        // we remove the active classes.
        $('a[class^=menu]').removeClass('active');
        $('div[class^=content]').removeClass('active');
    
        // we get the item that was clicked and select the item
        // in a dynamic way.
        const clickedClass = $(this).attr('class');
        const [identifier, number] = clickedClass.split('-')
    
        $(`.${clickedClass}`).addClass('active');
        $(`.content-${number}`).addClass('active');
    
      });
    
    
      const active = hash.substr(1);
      if (active != '') {
        $('a[class^=menu],div[class^=content]').removeClass('active');
    
    
        // making the content active
        $(`#${active}`).addClass('active');
    
    
        // making the menu active
        $(`a[href="mywebsite#${active}"]`).addClass("active")
    
      }
    
    });
    .container {
      margin: 0 auto;
      background-color: #eee;
      border: 1px solid lightgrey;
      width: 20vw;
      height: 90vh;
      font-family: sans-serif;
      position: relative;
    }
    
    header {
      background-color: lightgreen;
      padding: 5px;
      text-align: center;
      text-transform: uppercase;
    }
    
    .bottom-navbar {
      position: absolute;
      bottom: 0;
      width: 100%;
      padding: 6px 0;
      overflow: hidden;
      background-color: lightgreen;
      border-top: 1px solid var(--color-grey-dark-3);
      z-index: 50;
      display: flex;
      justify-content: space-between;
    }
    
    .bottom-navbar>a {
      display: block;
      color: green;
      text-align: center;
      text-decoration: none;
      font-size: 20px;
      padding: 0 10px;
    }
    
    .bottom-navbar>a.active {
      color: black;
    }
    
    .menu-1.active,
    .menu-2.active,
    .menu-3.active {
      color: black;
    }
    
    .content-1,
    .content-2,
    .content-3 {
      display: none;
    }
    
    .content-1.active,
    .content-2.active,
    .content-3.active {
      display: block;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translateX(-50%) translateY(-50%);
    }
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    
    
    <div class="container">
      <header>My header</header>
      <div class="main-content">
        <div class="content-1 active" id="firstPage">House content</div>
        <div class="content-2" id="secondPage">Map content</div>
        <div class="content-3" id="thirdPage">Explore content</div>
        <div class="bottom-navbar">
          <a href="mywebsite#firstPage" class="menu-1 active"><i class="fa fa-home"></i></a>
          <a href="mywebsite#secondPage" class="menu-2"><i class="fa fa-map"></i></a>
          <a href="mywebsite#thirdPage" class="menu-3"><i class="fa fa-search"></i></a>
        </div>
      </div>
    </div>