Search code examples
javascriptjquerygsap

Javascript Tabs - How to add hashtags on URL?


My Tabs works fine, but I need to have a separate function which directs with a URL to the tab, so I can have a separate link for each tab.

How Can I achieve that?

url.com/#tab1

url.com/#tab2

I tried many ways but I keep getting undefined hashtag. I'd like advice please, I put together a demo, which shows the full working experience.

var boxLink = $( '.but' );
var box = $( '.tab' );

boxLink.click( function() {
	$('#but1').removeClass('active');
 
    var boxID = $(this).attr("data-target");
    var currentbox = $('.tab:not(.is-hidden)');
    var targetBox = $('.tab#' + boxID);
    
    if (!$(this).hasClass('active'))    {
        boxLink.removeClass('active');
        $(this).addClass('active');

        TweenMax.to( currentbox, 0.2, {ease:Power4.easeOut, className: '-=visible', autoAlpha: 0,  onComplete: boxIn, onCompleteParams: [targetBox] });
    }
    
    return false;
});

var boxIn = function( targetBox ) {
    box.addClass( 'is-hidden' );
    targetBox.removeClass( 'is-hidden' );
    
    TweenMax.to( targetBox, 0.2, {autoAlpha: 1,className: '+=visible', ease:Power4.easeIn});
}
body {
  background-color:black;
 }
#tab01 {
background: white;
}

#tab02 {
background: red;
} 
 
.tab {
width:100px;
height:100px;
font-size:30px;
line-height:100px;
text-align:center;
}
.is-hidden {
  display: none;
  opacity:0;
  visibility:hidden;
} 

button {
  cursor:pointer;
  padding: 5px;
  margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="tab" id="tab01">one</div>
<div class="tab is-hidden" id="tab02">two</div>

<button  class="but active" id="but1" data-target="tab01">slide 1</button>
<button  class="but" id="but2" data-target="tab02">slide 2</button>


Solution

  • If I got you correctly, you want to show a specific tab on load in case a hash has been added to the page's URL, right? If so you should parse window.location.href and check for a hash tag in the URL. If it is present, the hash value e.g. '#tab2' should show the container with the same ID.

    Updated code:

    var currentUrl= window.location.href;
    if (currentUrl.indexOf('#') > -1) {
      var hashTag= currentUrl.substring(currentUrl.indexOf('#')+1);
      var targetBox = $('.tab#' + hashTag);
      TweenMax.to( currentbox, 0.2, {ease:Power4.easeOut, 
        className: '-=visible', autoAlpha: 0,  onComplete: boxIn, onCompleteParams: [targetBox] });
    
      // added: highlight the proper buttons and remove the default "active" element
      $('.active').removeClass('active');
      $('.' + hashTag + '-control').addClass('active');
    }
    

    To also highlight the buttons, you need to give them a class (that's the easiest method as you can't use duplicate IDs so we identify the tab via ID and button via class):

    <button  class="tab01-control but active" id="but1" data-target="tab01">slide 1</button>
    <button  class="tab02-control but" id="but2" data-target="tab02">slide 2</button>
    

    Your boxIn(targetBox) method expects to receive a jQuery object as "targetBox" parameter and it was a string. Simply append "#tab02" to your URL when you test it locally to have the second tab show up.

    Side note:

    Your Code snippet is currently not working correctly, you should include ...

    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.1.3/TweenMax.min.js"></script>
    

    ... to make your animation work as expected, otherwise you'll receive a JS error message when clicking one of the buttons.

    Edit 1

    As you asked how to use meaningful "hash names" instead of the control's IDs like tab01, this can be achieved with a simple switch-case:

    let hashTag = window.location.hash;
    if (hashTag !== '') {
        hashTag = hashTag.substring(1);
    
        let targetName = '';
    
        switch (hashTag) {
            case "home":
                targetName = 'tab01';
                break;
            case "profile":
                targetName = 'tab02';
                break;
        }
        if (targetName !== '') {
            var targetBox = $('.tab#' + targetName);
            ...
        }