Search code examples
javascriptjqueryhtmlhref

How do I let javascript animation finish before href is running


When I set href to a site in my project the javascript animation wont finish before it goes to the site. But if I set href="#0" it works.

Someone said X.preventDefault would work but it does not.

Appreciate any help I can get :).

Javascript:

jQuery(document).ready(function($){
//toggle 3d navigation
$('.cd-3d-nav-trigger').on('click', function(){
    toggle3dBlock(!$('.cd-header').hasClass('nav-is-visible'));

});

//select a new item from the 3d navigation
$('.cd-3d-nav a').on('click', function(){
    var selected = $(this);
    selected.parent('li').addClass('cd-selected').siblings('li').removeClass('cd-selected');
    updateSelectedNav('close');

});

$(window).on('resize', function(){
    window.requestAnimationFrame(updateSelectedNav);

});

function toggle3dBlock(addOrRemove) {
    if(typeof(addOrRemove)==='undefined') addOrRemove = true;   
    $('.cd-header').toggleClass('nav-is-visible', addOrRemove);
    $('main').toggleClass('nav-is-visible', addOrRemove);
    $('.cd-3d-nav-container').toggleClass('nav-is-visible', addOrRemove);

}

//this function update the .cd-marker position
function updateSelectedNav(type) {
    var selectedItem = $('.cd-selected').preventDefault(),
        selectedItemPosition = selectedItem.index() + 1, 
        leftPosition = selectedItem.offset().left,
        backgroundColor = selectedItem.data('color');


    $('.cd-marker').removeClassPrefix('color').addClass('color-'+ selectedItemPosition).css({
        'left': leftPosition,
    });
    if( type == 'close') {
        $('.cd-marker').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
            toggle3dBlock(false);
        });
    }
}

$.fn.removeClassPrefix = function(prefix) {
    this.each(function(i, el) {
        var classes = el.className.split(" ").filter(function(c) {
            return c.lastIndexOf(prefix, 0) !== 0;
        });
        el.className = $.trim(classes.join(" "));

    });
    return this;
};

});

HTML:

<header class="cd-header">
    <a href="#0" class="cd-logo"><img src="img/cd-logo.svg" alt="Logo"></a>
    <a href="#0" class="cd-3d-nav-trigger">
        Menu
        <span></span>
    </a>
</header> <!-- .cd-header -->



<nav class="cd-3d-nav-container">
    <ul class="cd-3d-nav">
        <li class="cd-selected">
            <a href="Default.aspx">Home</a>
        </li>
        <li>
            <a href="aboutme.aspx>About me</a>
        </li>

        <li>
            <a href="Portfolio.aspx" onclick="">Portfolio</a>
        </li>

        <li>
            <a href="Vouge approved.aspx">Vouge approved</a>
        </li>

        <li>
            <a href="Contact information.aspx">Contact information</a>
        </li>
    </ul> <!-- .cd-3d-nav -->

    <span class="cd-marker color-1"></span> 
</nav> <!-- .cd-3d-nav-container -->

Solution

  • Using preventDefault works to stop the navigation, but then you have to do the navigation using code when the animation is complete.

    Add a callback to the updateSelectedNav, so you can use that to do something when the animation completes:

    function updateSelectedNav(type, callback) {
    

    Call it in the event for the transition end:

      if( type == 'close') {
        $('.cd-marker').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(){
          toggle3dBlock(false);
          if (typeof callback == 'function') callback();
        });
      }
    

    Now you can use preventDefault to stop the navigation, and do it when the animation is complete:

    $('.cd-3d-nav a').on('click', function(e){
      e.preventDefault();
      var selected = $(this);
      selected.parent('li').addClass('cd-selected').siblings('li').removeClass('cd-selected');
      updateSelectedNav('close', function(){
        window.location.href = selected.attr('href');
      });
    });