/
githubmirror
/
Leaflet
Обзор
Документация
Войти
/
githubmirror
/
Leaflet
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/map/handler/TapHoldHandler.js
104 строки
3 KB
Volodymyr Agafonkin
Switch from Karma to Vitest (#10207)
11 май 2026, 17:22
Не верифицирован
11 май 2026, 17:22
87d3a14
Код
Авторство
О чём код?
import {LeafletMap} from '../Map.js'; import {Handler} from '../../core/Handler.js'; import * as DomEvent from '../../dom/DomEvent.js'; import {Point} from '../../geometry/Point.js'; import Browser from '../../core/Browser.js'; import * as PointerEvents from '../../dom/DomEvent.PointerEvents.js'; /* * TapHoldHandler is used to simulate `contextmenu` event on long hold, * which otherwise is not fired by mobile Safari. */ const tapHoldDelay = 600; // @namespace LeafletMap // @section Interaction Options LeafletMap.mergeOptions({ // @section Touch interaction options // @option tapHold: Boolean // Enables simulation of `contextmenu` event, default is `true` for mobile Safari. tapHold: Browser.safari && Browser.mobile, // @option tapTolerance: Number = 15 // The max number of pixels a user can shift his finger during touch // for it to be considered a valid tap. tapTolerance: 15 }); export class TapHoldHandler extends Handler { addHooks() { DomEvent.on(this._map._container, 'pointerdown', this._onDown, this); } removeHooks() { DomEvent.off(this._map._container, 'pointerdown', this._onDown, this); this._cancel(); this._cancelClickPrevent(); } _onDown(e) { clearTimeout(this._holdTimeout); if (PointerEvents.getPointers().length !== 1 || e.pointerType === 'mouse') { return; } const el = this._map._container; this._startPos = this._newPos = new Point(e.clientX, e.clientY); this._holdTimeout = setTimeout((() => { this._cancel(); if (!this._isTapValid()) { return; } // prevent simulated mouse events https://w3c.github.io/touch-events/#mouse-events DomEvent.on(el, 'pointerup', DomEvent.preventDefault); DomEvent.on(el, 'pointerup pointercancel', this._cancelClickPrevent, this); this._simulateEvent('contextmenu', e); }), tapHoldDelay); DomEvent.on(el, 'pointerup pointercancel contextmenu', this._cancel, this); DomEvent.on(el, 'pointermove', this._onMove, this); } _cancelClickPrevent() { const el = this._map._container; DomEvent.off(el, 'pointerup', DomEvent.preventDefault); DomEvent.off(el, 'pointerup pointercancel', this._cancelClickPrevent, this); }; _cancel() { clearTimeout(this._holdTimeout); const el = this._map._container; DomEvent.off(el, 'pointerup pointercancel contextmenu', this._cancel, this); DomEvent.off(el, 'pointermove', this._onMove, this); } _onMove(e) { this._newPos = new Point(e.clientX, e.clientY); } _isTapValid() { return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance; } _simulateEvent(type, e) { const simulatedEvent = new MouseEvent(type, { bubbles: true, cancelable: true, view: window, // detail: 1, screenX: e.screenX, screenY: e.screenY, clientX: e.clientX, clientY: e.clientY, // button: 2, // buttons: 2 }); simulatedEvent._simulated = true; e.target.dispatchEvent(simulatedEvent); } } // @section Handlers // @property tapHold: Handler // Long tap handler to simulate `contextmenu` event (useful in mobile Safari). LeafletMap.addInitHook('addHandler', 'tapHold', TapHoldHandler);