UNPKG

leaflet

Version:

JavaScript library for mobile-friendly interactive maps

132 lines (101 loc) 4.07 kB
/* * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. */ L.extend(L.DomEvent, { POINTER_DOWN: L.Browser.msPointer ? 'MSPointerDown' : 'pointerdown', POINTER_MOVE: L.Browser.msPointer ? 'MSPointerMove' : 'pointermove', POINTER_UP: L.Browser.msPointer ? 'MSPointerUp' : 'pointerup', POINTER_CANCEL: L.Browser.msPointer ? 'MSPointerCancel' : 'pointercancel', TAG_WHITE_LIST: ['INPUT', 'SELECT', 'OPTION'], _pointers: {}, _pointersCount: 0, // Provides a touch events wrapper for (ms)pointer events. // ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 addPointerListener: function (obj, type, handler, id) { if (type === 'touchstart') { this._addPointerStart(obj, handler, id); } else if (type === 'touchmove') { this._addPointerMove(obj, handler, id); } else if (type === 'touchend') { this._addPointerEnd(obj, handler, id); } return this; }, removePointerListener: function (obj, type, id) { var handler = obj['_leaflet_' + type + id]; if (type === 'touchstart') { obj.removeEventListener(this.POINTER_DOWN, handler, false); } else if (type === 'touchmove') { obj.removeEventListener(this.POINTER_MOVE, handler, false); } else if (type === 'touchend') { obj.removeEventListener(this.POINTER_UP, handler, false); obj.removeEventListener(this.POINTER_CANCEL, handler, false); } return this; }, _addPointerStart: function (obj, handler, id) { var onDown = L.bind(function (e) { if (e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) { // In IE11, some touch events needs to fire for form controls, or // the controls will stop working. We keep a whitelist of tag names that // need these events. For other target tags, we prevent default on the event. if (this.TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) { L.DomEvent.preventDefault(e); } else { return; } } this._handlePointer(e, handler); }, this); obj['_leaflet_touchstart' + id] = onDown; obj.addEventListener(this.POINTER_DOWN, onDown, false); // need to keep track of what pointers and how many are active to provide e.touches emulation if (!this._pointerDocListener) { var pointerUp = L.bind(this._globalPointerUp, this); // we listen documentElement as any drags that end by moving the touch off the screen get fired there document.documentElement.addEventListener(this.POINTER_DOWN, L.bind(this._globalPointerDown, this), true); document.documentElement.addEventListener(this.POINTER_MOVE, L.bind(this._globalPointerMove, this), true); document.documentElement.addEventListener(this.POINTER_UP, pointerUp, true); document.documentElement.addEventListener(this.POINTER_CANCEL, pointerUp, true); this._pointerDocListener = true; } }, _globalPointerDown: function (e) { this._pointers[e.pointerId] = e; this._pointersCount++; }, _globalPointerMove: function (e) { if (this._pointers[e.pointerId]) { this._pointers[e.pointerId] = e; } }, _globalPointerUp: function (e) { delete this._pointers[e.pointerId]; this._pointersCount--; }, _handlePointer: function (e, handler) { e.touches = []; for (var i in this._pointers) { e.touches.push(this._pointers[i]); } e.changedTouches = [e]; handler(e); }, _addPointerMove: function (obj, handler, id) { var onMove = L.bind(function (e) { // don't fire touch moves when mouse isn't down if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; } this._handlePointer(e, handler); }, this); obj['_leaflet_touchmove' + id] = onMove; obj.addEventListener(this.POINTER_MOVE, onMove, false); }, _addPointerEnd: function (obj, handler, id) { var onUp = L.bind(function (e) { this._handlePointer(e, handler); }, this); obj['_leaflet_touchend' + id] = onUp; obj.addEventListener(this.POINTER_UP, onUp, false); obj.addEventListener(this.POINTER_CANCEL, onUp, false); } });