Tappable demo

https://github.com/cheeaun/tappable

HTML

<script src="https://raw.github.com/cheeaun/tappable/master/source/tappable.js"></script>
<input type="text" placeholder="Place focus on me first!" />
<br>
<div id="a" href="#">
  <p>
  Then tap me
  </p>
</div>

CSS

*{
    -webkit-text-size-adjust: none;
    font-family: sans-serif;
}
html, body{
    min-height: 150%;
}
#a{
    border: 2px solid #aaa;
    display: inline-block;
    width: 120px;
    height: 120px;
    margin: 10px 10px;
    vertical-align: middle;
    text-decoration: none;
    font-size: 12px;
    background-color: blue;
}
#a.tappable-active{
    color: #fff;
    background-color: red;
}
</style>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>

JavaScript

(function(root, factory){
  // Set up Tappable appropriately for the environment.
  if (typeof define === 'function' && define.amd){
    // AMD
    define('tappable', [], function(){
      factory(root, window.document);
      return root.tappable;
    });
  } else {
    // Browser global scope
    factory(root, window.document);
  }
}(this, function(w, d){

  var abs = Math.abs,
    noop = function(){},
    defaults = {
      noScroll: false,
      activeClass: 'tappable-active',
      onTap: noop,
      onStart: noop,
      onMove: noop,
      onMoveOut: noop,
      onMoveIn: noop,
      onEnd: noop,
      onCancel: noop,
      allowClick: false,
      boundMargin: 50,
      noScrollDelay: 0,
      activeClassDelay: 0,
      inactiveClassDelay: 0
    },
    supportTouch = 'ontouchend' in document,
    events = {
      start: supportTouch ? 'touchstart' : 'mousedown',
      move: supportTouch ? 'touchmove' : 'mousemove',
      end: supportTouch ? 'touchend' : 'mouseup'
    },
    getTargetByCoords = function(x, y){
      var el = d.elementFromPoint(x, y);
      if (el.nodeType == 3) el = el.parentNode;
      return el;
    },
    getTarget = function(e){
      var el = e.target;
      if (el) {
        if (el.nodeType == 3) el = el.parentNode;
        return el;
      }
      var touch = e.targetTouches[0];
      return getTargetByCoords(touch.clientX, touch.clientY);
    },
    clean = function(str){
      return str.replace(/\s+/g, ' ').replace(/^\s+|\s+$/g, '');
    },
    addClass = function(el, className){
      if (!className) return;
      if (el.classList){
        el.classList.add(className);
        return;
      }
      if (clean(el.className).indexOf(className) > -1) return;
      el.className = clean(el.className + ' ' + className);
    },
    removeClass = function(el, className){
      if (!className) return;
      if (el.classList){
        el.classList.remove(className);
        return;
      }
      el.className = el.className.replace(new...