From d133c86b510df29c404dc3df27e3bccccaa5a7a4 Mon Sep 17 00:00:00 2001 From: danzel Date: Wed, 29 Aug 2012 16:03:54 +1200 Subject: [PATCH] Add LongPress support to mobile. Fires a contextmenu event after a single press without movement of 1 second --- build/deps.js | 1 + debug/leaflet-include.js | 1 + src/dom/DomEvent.LongPress.js | 60 +++++++++++++++++++++++++++++++++++ src/dom/DomEvent.js | 3 ++ 4 files changed, 65 insertions(+) create mode 100644 src/dom/DomEvent.LongPress.js diff --git a/build/deps.js b/build/deps.js index ff8fa15b..5f36cdab 100644 --- a/build/deps.js +++ b/build/deps.js @@ -170,6 +170,7 @@ var deps = { src: ['dom/DomEvent.js', 'dom/DomEvent.DoubleTap.js', 'dom/DomEvent.MsTouch.js', + 'dom/DomEvent.LongPress.js', 'core/Handler.js', 'map/handler/Map.TouchZoom.js'], deps: ['MapAnimationZoom'], diff --git a/debug/leaflet-include.js b/debug/leaflet-include.js index 6833ff10..d2d73390 100644 --- a/debug/leaflet-include.js +++ b/debug/leaflet-include.js @@ -17,6 +17,7 @@ 'dom/DomEvent.js', 'dom/DomEvent.DoubleTap.js', 'dom/DomEvent.MsTouch.js', + 'dom/DomEvent.LongPress.js', 'dom/DomUtil.js', 'dom/Draggable.js', diff --git a/src/dom/DomEvent.LongPress.js b/src/dom/DomEvent.LongPress.js new file mode 100644 index 00000000..4384c1b0 --- /dev/null +++ b/src/dom/DomEvent.LongPress.js @@ -0,0 +1,60 @@ +L.Util.extend(L.DomEvent, { + // inspired by Zepto touch code by Thomas Fuchs + addLongPressListener: function (obj, handler, id) { + var touch, + start, + timeoutId = null, + delay = 1000, + maxMovement = 10, + diffX, diffY, + pre = '_leaflet_', + touchstart = 'touchstart', + touchmove = 'touchmove', + touchend = 'touchend'; + + function onTouchStart(e) { + clearTimeout(timeoutId); + + if (e.touches.length !== 1) { + return; + } + + touch = e.touches[0]; + start = Date.now(); + + timeoutId = setTimeout(function () { + touch.type = 'contextmenu'; + handler(touch); + }, delay); + } + + function onTouchMove(e) { + diffX = e.touches[0].pageX - touch.pageX; + diffY = e.touches[0].pageY - touch.pageY; + + if (diffX * diffX + diffY * diffY > maxMovement * maxMovement) { + clearTimeout(timeoutId); + } + } + + function onTouchEnd() { + clearTimeout(timeoutId); + } + obj[pre + touchstart + id] = onTouchStart; + obj[pre + touchmove + id] = onTouchMove; + obj[pre + touchend + id] = onTouchEnd; + + obj.addEventListener(touchstart, onTouchStart, false); + obj.addEventListener(touchmove, onTouchMove, false); + obj.addEventListener(touchend, onTouchEnd, false); + return this; + }, + + removeLongPressListener: function (obj, id) { + var pre = '_leaflet_'; + obj.removeEventListener(obj, obj[pre + 'touchstart' + id], false); + obj.removeEventListener(obj, obj[pre + 'touchmove' + id], false); + obj.removeEventListener(obj, obj[pre + 'touchend' + id], false); + return this; + } +}); diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index 85141509..2d619a91 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -21,6 +21,9 @@ L.DomEvent = { } else if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) { return this.addDoubleTapListener(obj, handler, id); + } else if (L.Browser.touch && (type === 'contextmenu') && this.addLongPressListener) { + return this.addLongPressListener(obj, handler, id); + } else if ('addEventListener' in obj) { if (type === 'mousewheel') {