123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- define("dojo/touch", ["./_base/kernel", "./aspect", "./dom", "./on", "./has", "./mouse", "./domReady", "./_base/window"],
- function(dojo, aspect, dom, on, has, mouse, domReady, win){
- // module:
- // dojo/touch
- var hasTouch = has("touch");
- // TODO: get iOS version from dojo/sniff after #15827 is fixed
- var ios4 = false;
- if(has("ios")){
- var ua = navigator.userAgent;
- var v = ua.match(/OS ([\d_]+)/) ? RegExp.$1 : "1";
- var os = parseFloat(v.replace(/_/, '.').replace(/_/g, ''));
- ios4 = os < 5;
- }
- // Time of most recent touchstart or touchmove event
- var lastTouch;
- function dualEvent(mouseType, touchType){
- // Returns synthetic event that listens for both the specified mouse event and specified touch event.
- // But ignore fake mouse events that were generated due to the user touching the screen.
- if(hasTouch){
- return function(node, listener){
- var handle1 = on(node, touchType, listener),
- handle2 = on(node, mouseType, function(evt){
- if(!lastTouch || (new Date()).getTime() > lastTouch + 1000){
- listener.call(this, evt);
- }
- });
- return {
- remove: function(){
- handle1.remove();
- handle2.remove();
- }
- };
- };
- }else{
- // Avoid creating listeners for touch events on performance sensitive older browsers like IE6
- return function(node, listener){
- return on(node, mouseType, listener);
- }
- }
- }
- var touchmove, hoveredNode;
- if(hasTouch){
- domReady(function(){
- // Keep track of currently hovered node
- hoveredNode = win.body(); // currently hovered node
- win.doc.addEventListener("touchstart", function(evt){
- lastTouch = (new Date()).getTime();
- // Precede touchstart event with touch.over event. DnD depends on this.
- // Use addEventListener(cb, true) to run cb before any touchstart handlers on node run,
- // and to ensure this code runs even if the listener on the node does event.stop().
- var oldNode = hoveredNode;
- hoveredNode = evt.target;
- on.emit(oldNode, "dojotouchout", {
- target: oldNode,
- relatedTarget: hoveredNode,
- bubbles: true
- });
- on.emit(hoveredNode, "dojotouchover", {
- target: hoveredNode,
- relatedTarget: oldNode,
- bubbles: true
- });
- }, true);
- // Fire synthetic touchover and touchout events on nodes since the browser won't do it natively.
- on(win.doc, "touchmove", function(evt){
- lastTouch = (new Date()).getTime();
- var newNode = win.doc.elementFromPoint(
- evt.pageX - (ios4 ? 0 : win.global.pageXOffset), // iOS 4 expects page coords
- evt.pageY - (ios4 ? 0 : win.global.pageYOffset)
- );
- if(newNode && hoveredNode !== newNode){
- // touch out on the old node
- on.emit(hoveredNode, "dojotouchout", {
- target: hoveredNode,
- relatedTarget: newNode,
- bubbles: true
- });
- // touchover on the new node
- on.emit(newNode, "dojotouchover", {
- target: newNode,
- relatedTarget: hoveredNode,
- bubbles: true
- });
- hoveredNode = newNode;
- }
- });
- });
- // Define synthetic touch.move event that unlike the native touchmove, fires for the node the finger is
- // currently dragging over rather than the node where the touch started.
- touchmove = function(node, listener){
- return on(win.doc, "touchmove", function(evt){
- if(node === win.doc || dom.isDescendant(hoveredNode, node)){
- evt.target = hoveredNode;
- listener.call(this, evt);
- }
- });
- };
- }
- //device neutral events - touch.press|move|release|cancel/over/out
- var touch = {
- press: dualEvent("mousedown", "touchstart"),
- move: dualEvent("mousemove", touchmove),
- release: dualEvent("mouseup", "touchend"),
- cancel: dualEvent(mouse.leave, "touchcancel"),
- over: dualEvent("mouseover", "dojotouchover"),
- out: dualEvent("mouseout", "dojotouchout"),
- enter: mouse._eventHandler(dualEvent("mouseover","dojotouchover")),
- leave: mouse._eventHandler(dualEvent("mouseout", "dojotouchout"))
- };
- /*=====
- touch = {
- // summary:
- // This module provides unified touch event handlers by exporting
- // press, move, release and cancel which can also run well on desktop.
- // Based on http://dvcs.w3.org/hg/webevents/raw-file/tip/touchevents.html
- //
- // example:
- // Used with dojo.on
- // | define(["dojo/on", "dojo/touch"], function(on, touch){
- // | on(node, touch.press, function(e){});
- // | on(node, touch.move, function(e){});
- // | on(node, touch.release, function(e){});
- // | on(node, touch.cancel, function(e){});
- // example:
- // Used with touch.* directly
- // | touch.press(node, function(e){});
- // | touch.move(node, function(e){});
- // | touch.release(node, function(e){});
- // | touch.cancel(node, function(e){});
- press: function(node, listener){
- // summary:
- // Register a listener to 'touchstart'|'mousedown' for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- move: function(node, listener){
- // summary:
- // Register a listener to 'touchmove'|'mousemove' for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- release: function(node, listener){
- // summary:
- // Register a listener to 'touchend'|'mouseup' for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- cancel: function(node, listener){
- // summary:
- // Register a listener to 'touchcancel'|'mouseleave' for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- over: function(node, listener){
- // summary:
- // Register a listener to 'mouseover' or touch equivalent for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- out: function(node, listener){
- // summary:
- // Register a listener to 'mouseout' or touch equivalent for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- enter: function(node, listener){
- // summary:
- // Register a listener to mouse.enter or touch equivalent for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- },
- leave: function(node, listener){
- // summary:
- // Register a listener to mouse.leave or touch equivalent for the given node
- // node: Dom
- // Target node to listen to
- // listener: Function
- // Callback function
- // returns:
- // A handle which will be used to remove the listener by handle.remove()
- }
- };
- =====*/
- 1 && (dojo.touch = touch);
- return touch;
- });
|