Last active
December 29, 2016 15:16
-
-
Save w3core/5419adba065b9ab5a07f99a729b79da0 to your computer and use it in GitHub Desktop.
Cross-browser implementation of swipe events for the any element by using mouse and touch native events.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Swipe v.1.0.0 | |
* ============= | |
* Cross-browser implementation of swipe events for the any element | |
* by using mouse and touch native events. It allows to handle events such | |
* as "swipestart", "swipemove" and "swipeend". | |
* | |
* @license MIT | |
* @author Max Chuhryaev | |
* | |
* Usage example | |
* ------------- | |
* ```javascript | |
* var node = document.body; | |
* node.addEventListener("swipestart", swipeListener, !1); | |
* node.addEventListener("swipemove", swipeListener, !1); | |
* node.addEventListener("swipeend", swipeListener, !1); | |
* | |
* Swipe(node, function (data) { | |
* console.log("handler", data.type, data, this); | |
* }); | |
* | |
* function swipeListener (event) { | |
* console.log("listener", event.type, event); | |
* } | |
* ``` | |
* | |
* @param node (HTMLElement|String) [Required] HTML element or CSS selector of elements that should emit swipe events | |
* @param handler (Function) [Optional] An optional function that can be used to | |
* handle swipe events and preventing of original events. | |
* @returns void | |
*/ | |
function Swipe (node, handler) { | |
var hasTouch = "ontouchstart" in window, | |
startEvent = hasTouch ? 'touchstart' : 'mousedown', | |
moveEvent = hasTouch ? 'touchmove' : 'mousemove', | |
dragEvent = hasTouch ? '' : 'dragover', | |
endEvent = hasTouch ? 'touchend' : 'mouseup', | |
cancelEvent = hasTouch ? 'touchcancel' : 'dragend' | |
; | |
var round = Math.round; | |
var root, startX, x, startY, y, way, direction; | |
constructor(); | |
function constructor () { | |
window.addEventListener(startEvent, listener, !1); | |
window.addEventListener(moveEvent, listener, !1); | |
if (dragEvent) window.addEventListener(dragEvent, listener, !1); | |
window.addEventListener(endEvent, listener, !1); | |
window.addEventListener(cancelEvent, listener, !1); | |
} | |
function listener (e) { | |
if (e.type == startEvent) { | |
var node = getEventNode(e); | |
if (node) root = node; | |
} | |
if (root) { | |
var current = pointerLocationByEvent(e); | |
if (e.type == startEvent) { | |
startX = x = current.x; | |
startY = y = current.y; | |
fire("start", e); | |
} | |
else if (e.type == moveEvent || e.type == dragEvent) { | |
if (!way) { | |
var wdX = calcDiff(startX, current.x), wdY = calcDiff(startY, current.y); | |
if (wdX == wdY) return; | |
way = wdX > wdY ? "x" : "y"; | |
} | |
direction = way == "x" ? (x>current.x?"left":"right") : (y>current.y?"top":"bottom"); | |
x = current.x; | |
y = current.y; | |
fire("move", e); | |
} | |
else if (e.type == endEvent || e.type == cancelEvent) { | |
fire("end", e); | |
root = null; | |
way = direction = null; | |
} | |
} | |
} | |
function getEventNode (e) { | |
if (typeof node == "string") return bySelector(e.target, node, !0); | |
else return byNode(e.target, node); | |
} | |
function _matchesSelector(el, selector) { | |
if (el == window || el == document) return !1; | |
var p = Element.prototype; | |
var f = p.matches || p.webkitMatchesSelector || p.mozMatchesSelector || p.msMatchesSelector || function(s) { | |
return [].indexOf.call(document.querySelectorAll(s), this) !== -1; | |
}; | |
return f.call(el, selector); | |
} | |
function bySelector (el, selector, closest) { | |
if (_matchesSelector(el, selector)) return el; | |
if (!closest) return !1; | |
return el.parentNode ? bySelector (el.parentNode, selector, closest) : !1; | |
} | |
function byNode (node, parent) { | |
if (node == parent) return node; | |
return node.parentNode ? byNode(node.parentNode, parent) : false; | |
} | |
function calcDiff (prev, current) { | |
return Math.max(prev, current) - Math.min(prev, current); | |
} | |
function pointerLocationByEvent (e) { | |
var v = e.touches && e.touches[0] ? e.touches[0] : e; | |
return { | |
x: round(v.clientX || v.pageX || v.x), | |
y: round(v.clientY || v.pageY || v.y) | |
}; | |
} | |
function getData (originalEvent) { | |
var o = { | |
x:x, | |
y:y, | |
startX:startX, | |
startY:startY, | |
diffX:x-startX, | |
diffY:y-startY | |
}; | |
if (originalEvent) o.originalEvent = originalEvent; | |
if (way) { | |
o.way = way; | |
o.diffWay = way=="x"?o.diffX:o.diffY; | |
} | |
if (direction) o.direction = direction; | |
return o; | |
} | |
function fire (type, originalEvent) { | |
var event = "swipe"+type; | |
var data = getData(originalEvent); | |
var e = dispatch(root, event, data); | |
if (typeof handler == "function") handler.call(root, e); | |
} | |
function dispatch (node, event, data) { | |
var e = document.createEvent("HTMLEvents"); | |
if (data) for (var i in data) e[i] = data[i]; | |
e.initEvent(event, true, true); | |
node.dispatchEvent(e); | |
return e; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Swipe(h,v){function e(a){var c,b;a.type==r&&(c="string"==typeof h?w(a.target,h,!0):x(a.target,h),c&&(k=c));if(k)if(b=a.touches&&a.touches[0]?a.touches[0]:a,c=y(b.clientX||b.pageX||b.x),b=y(b.clientY||b.pageY||b.y),a.type==r)l=m=c,n=p=b,t("start",a);else if(a.type==z||a.type==u){if(!g){var d=Math.max(l,c)-Math.min(l,c),e=Math.max(n,b)-Math.min(n,b);if(d==e)return;g=d>e?"x":"y"}q="x"==g?m>c?"left":"right":p>b?"top":"bottom";m=c;p=b;t("move",a)}else if(a.type==A||a.type==B)t("end",a),g=q=k=null}function C(a,c){if(a==window||a==document)return!1;var b=Element.prototype;return(b.matches||b.webkitMatchesSelector||b.mozMatchesSelector||b.msMatchesSelector||function(a){return-1!==[].indexOf.call(document.querySelectorAll(a),this)}).call(a,c)}function w(a,c,b){return C(a,c)?a:b?a.parentNode?w(a.parentNode,c,b):!1:!1}function x(a,c){return a==c?a:a.parentNode?x(a.parentNode,c):!1}function t(a,c){var b="swipe"+a,d={x:m,y:p,startX:l,startY:n,diffX:m-l,diffY:p-n};c&&(d.originalEvent=c);g&&(d.way=g,d.diffWay="x"==g?d.diffX:d.diffY);q&&(d.direction=q);var e=k,f=document.createEvent("HTMLEvents");if(d)for(var h in d)f[h]=d[h];f.initEvent(b,!0,!0);e.dispatchEvent(f);"function"==typeof v&&v.call(k,f)}var f="ontouchstart"in window,r=f?"touchstart":"mousedown",z=f?"touchmove":"mousemove",u=f?"":"dragover",A=f?"touchend":"mouseup",B=f?"touchcancel":"dragend",y=Math.round,k,l,m,n,p,g,q;window.addEventListener(r,e,!1);window.addEventListener(z,e,!1);u&&window.addEventListener(u,e,!1);window.addEventListener(A,e,!1);window.addEventListener(B,e,!1)}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Swipe v.1.0.0
Cross-browser implementation of swipe events for the any element
by using mouse and touch native events. It allows to handle events such
as "swipestart", "swipemove" and "swipeend".
Usage example
Working example