Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to listen to the end of a bootstrap animation

I'm developing a website using bootstrap and its responsive JS+CSS.

At the top of the page I have a fixed navigation bar where an "expand menu" button is shown in case the viewport is too tight. This button does its magic with an animation (a CSS3 one I think) and I'm happy with it, but I would like to do something more (toggle classes with jquery) each time the animation finishes (both the open animation and the close one). I was thinking about a javascript listener (even better by defining it thanks to jquery .on function), but I really don't know what event I should listen to! Any ideas?

UPDATE I've fond out that by listening to this event on the object I wanna control almost does the job well:

$("#main-navbar .nav-collapse").on("transitionend", function(event){    
    console.log("end of the animation");
}

the only problem is that it messes bootstrap animations up on that object: the first time it works, but wen I want to close the expanded navbar, nothing happens (it seems that my listener overrides the bootstrap ones. quite weird, huh?)

like image 977
Bertuz Avatar asked Apr 10 '13 00:04

Bertuz


2 Answers

If you use bootstrap and transitions (css3 transition) you can try this:

$("body").on($.support.transition.end, '#main-navbar .nav-collapse', function(event){    
    console.log("end of the animation");
});

$.support.transition.end contains one of these events: webkitTransitionEnd, transitionend, oTransitionEnd otransitionend, transitionend.

But if you use css3 animation (css3 animation-name and keyframes) you can try this:

$("body").on('webkitAnimationEnd oanimationend msAnimationEnd animationend', '#main-navbar .nav-collapse', function(event){    
    console.log("end of the animation");
});
like image 147
v.babak Avatar answered Oct 24 '22 11:10

v.babak


$target.on("shown.bs.collapse", function(event){    
    console.log("end of the animation");
});

Wonder that nobody mention about Util.emulateTransitionEnd() which was created on purpose and used by Bootstrap components to catch when the animation is over.

$('#nav')
  .one(
    'bsTransitionEnd', // Util.TRANSITION_END
    handler
  )
  .emulateTransitionEnd(600); // Collapse.TRANSITION_DURATION

In your particular case, you might want to extend corresponding Bootstrap plugin, so that you can figure out which exactly case is yours - Collapse is used by different components.

Here is jsfiddle snippet to demo (based on Bootstrap v4).

jsfiddle.net/ru5ow96z

(function($) {
  var Collapse = $.fn.collapse.Constructor;
  var navbar = $('#nav');

  $.extend(Collapse.Default, {
    navbarClass: ''
  });

  var _show = Collapse.prototype.show;
  Collapse.prototype.show = function() {
    _show.apply(this, Array.prototype.slice.apply(arguments));

    var navbarClass = this._config.navbarClass;
    if (navbarClass && !navbar.hasClass(navbarClass)) {
      navbar.addClass(navbarClass);
    }
  }

  var _hide = Collapse.prototype.hide;
  Collapse.prototype.hide = function() {
    _hide.apply(this, Array.prototype.slice.apply(arguments));

    var navbarClass = this._config.navbarClass;
    if (navbarClass && navbar.hasClass(navbarClass)) {
      navbar
        .one('bsTransitionEnd', function() { // Util.TRANSITION_END
          navbar.removeClass(navbarClass);
        })
        .emulateTransitionEnd(300); // Collapse.TRANSITION_DURATION / 2
    }
  }
})(window.jQuery);
<nav id="nav" role="navigation" class="navbar fixed-top navbar-light bg-light">
  <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#nav_items" data-navbar-class="navbar-dark bg-dark" aria-expanded="false" aria-label="Menu">
    <span class="text-hide">Menu</span>
    <span class="navbar-toggler-icon"></span>
  </button>

  <div id="nav_items" class="collapse navbar-collapse">
    <div class="nav navbar-nav">
      <a class="nav-item nav-link active" href="">Link <span class="sr-only">Home</span></a>
      <a class="nav-item nav-link" href="">Link2</a>
      <a class="nav-item nav-link" href="">Link3</a>
    </div>
  </div>
</nav>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
<style type="text/css">
  button:focus {
    outline-width: 0;
  }

  .navbar-collapse.collapse.show {
    height: 100vh;
  }

  .navbar-nav {
    height: 100vh;
  }

  .navbar-toggler {
    border: none;
    padding: 0.25rem 0;
  }

  .navbar-dark .navbar-toggler-icon {
    background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,.5)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='18' y1='6' x2='6' y2='18'%3E%3C/line%3E%3Cline x1='6' y1='6' x2='18' y2='18'%3E%3C/line%3E%3C/svg%3E");
  }
</style>

<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/js/bootstrap.min.js" integrity="sha384-a5N7Y/aK3qNeh15eJKGWxsqtnX/wWdSZSKp+81YjTmS15nvnvxKHuzaWwXHDli+4" crossorigin="anonymous"></script>
like image 33
alextunyk Avatar answered Oct 24 '22 12:10

alextunyk