Single transition events

Executes the handler once for multiple transition events fired from a single action

by cent cent

HTML

<div id="parent">
  <div id="1" class="box">
   #1
  </div>
  <div id="2" class="box">
   #2
  </div>
  <div id="3" class="box">
   #3
  </div>

  <div id="console">
   
  </div>
  
  <div>
    <label for="clever">  
      Use oneTransition?
    </label>
    <input id="clever" type="checkbox">
    </div>
    <div>
    <label for="start">  
      at start?
    </label>
    <input id="start" type="checkbox">
  </div>
  <button id="clear">
    Clear
  </button>
</div>

CSS

* {
  box-sizing: border-box;
}
#parent {
  background-color: lightgray;
  height: 100vh;
  width: 100vw;
  border: 0;
  padding: 1rem;
  margin: 0;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
}
.box {
  display: block;
  margin: 1rem auto;
  width: 5rem;
  height: 2rem;
  color: white;
  text-align: center;
  vertical-align: middle;
  cursor: pointer;
  background-color: rgb(255, 87, 51);
  transition: all 500ms ease; 
}
#console {
  padding: .3rem;
  background-color: gray;
  color: white;
  text-align: center;
}

JavaScript

(function(){
   var width = $('.box').eq(0).width();
   
   var start = 'webkitTransitionStart otransitionstart oTransitionStart msTransitionStart transitionstart';
   
   var end = 'webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend';
   
   var handler;
   
   var type;
   
   //////////////////////////////////
   // initiate variables from page //
   //////////////////////////////////
   if($('#clever').prop('checked'))
      handler = cleverTransitionHandler;
   else
      handler = dummyTransitionHandler;
   if($('#start').prop('checked'))
      type = start;
   else
      type = end;
   
   // produce transition events!
   $('.box').on('click', function() {
      if($(this).width() > width)
      	$('.box').width('5rem');
      else
         $('.box').width('12rem');
   });
   
   // clear console
   $('#clear').on('click', function() {
      $('#console').html('');
   });

   //////////////////////////////////////////
   // initial handler of transition events //
   //////////////////////////////////////////
   $('#parent').on(type, handler);

   ///////////////////////////////////////
   // change handler to dummy or clever //
   ///////////////////////////////////////
   $('#clever').on('change', function() {
      // THIS IS CRITICAL (for the example code)!
      // you can't simply change handlers without removing previous ones!
      $('#parent').off(start).off(end);
     
      if($(this).prop('checked') == true){
         handler = cleverTransitionHandler;
         handler();
      }else{
     	   handler = dummyTransitionHandler;
         $('#parent').on(type, handler);
      }
   });

   //////////////////////////////////////////
   // change transition event to start/end //
   //////////////////////////////////////////
   $('#start').on('change', function() {
      // THIS IS CRITICAL (for the example code)!
      // you can't simply change handlers without removing previous ones
     ...