From cc24ec1be64b20814b371b860fba8dbb8b464888 Mon Sep 17 00:00:00 2001 From: Andreas Hocevar Date: Thu, 24 Oct 2019 16:03:23 +0200 Subject: [PATCH] Set touch-action to allow page scrolling --- src/ol/MapBrowserEventHandler.js | 1 - src/ol/PluggableMap.js | 36 +++++++++++++++++++++++++++++--- src/ol/events/EventType.js | 2 ++ test/spec/ol/map.test.js | 15 +++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/ol/MapBrowserEventHandler.js b/src/ol/MapBrowserEventHandler.js index 89b603f17f..0a6425974c 100644 --- a/src/ol/MapBrowserEventHandler.js +++ b/src/ol/MapBrowserEventHandler.js @@ -61,7 +61,6 @@ class MapBrowserEventHandler extends EventTarget { this.down_ = null; const element = this.map_.getViewport(); - element.setAttribute('touch-action', 'none'); /** * @type {number} diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 51a5853c97..75e8e204a8 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -131,6 +131,17 @@ import {toUserCoordinate, fromUserCoordinate} from './proj.js'; */ +/** + * @param {HTMLElement} element Element. + * @param {string} touchAction Value for `touch-action'. + */ +function setTouchAction(element, touchAction) { + element.style.msTouchAction = touchAction; + element.style.touchAction = touchAction; + element.setAttribute('touch-action', touchAction); +} + + /** * @fires import("./MapBrowserEvent.js").MapBrowserEvent * @fires import("./MapEvent.js").MapEvent @@ -246,9 +257,7 @@ class PluggableMap extends BaseObject { this.viewport_.style.overflow = 'hidden'; this.viewport_.style.width = '100%'; this.viewport_.style.height = '100%'; - // prevent page zoom on IE >= 10 browsers - this.viewport_.style.msTouchAction = 'none'; - this.viewport_.style.touchAction = 'none'; + /** * @private @@ -296,6 +305,12 @@ class PluggableMap extends BaseObject { */ this.keyHandlerKeys_ = null; + /** + * @private + * @type {?Array} + */ + this.focusHandlerKeys_ = null; + const handleBrowserEvent = this.handleBrowserEvent.bind(this); this.viewport_.addEventListener(EventType.CONTEXTMENU, handleBrowserEvent, false); this.viewport_.addEventListener(EventType.WHEEL, handleBrowserEvent, false); @@ -1028,6 +1043,12 @@ class PluggableMap extends BaseObject { targetElement = this.getTargetElement(); } + if (this.focusHandlerKeys_) { + for (let i = 0, ii = this.focusHandlerKeys_.length; i < ii; ++i) { + unlistenByKey(this.focusHandlerKeys_[i]); + } + this.focusHandlerKeys_ = null; + } if (this.keyHandlerKeys_) { for (let i = 0, ii = this.keyHandlerKeys_.length; i < ii; ++i) { unlistenByKey(this.keyHandlerKeys_[i]); @@ -1056,6 +1077,15 @@ class PluggableMap extends BaseObject { if (!this.renderer_) { this.renderer_ = this.createRenderer(); } + let hasFocus = true; + if (targetElement.hasAttribute('tabindex')) { + hasFocus = document.activeElement === targetElement; + this.focusHandlerKeys_ = [ + listen(targetElement, EventType.FOCUS, setTouchAction.bind(this, this.viewport_, 'none')), + listen(targetElement, EventType.BLUR, setTouchAction.bind(this, this.viewport_, 'auto')) + ]; + } + setTouchAction(this.viewport_, hasFocus ? 'none' : 'auto'); const keyboardEventTarget = !this.keyboardEventTarget_ ? targetElement : this.keyboardEventTarget_; diff --git a/src/ol/events/EventType.js b/src/ol/events/EventType.js index 46b9e21ef4..26594c960b 100644 --- a/src/ol/events/EventType.js +++ b/src/ol/events/EventType.js @@ -21,6 +21,7 @@ export default { */ ERROR: 'error', + BLUR: 'blur', CLEAR: 'clear', CONTEXTMENU: 'contextmenu', CLICK: 'click', @@ -28,6 +29,7 @@ export default { DRAGENTER: 'dragenter', DRAGOVER: 'dragover', DROP: 'drop', + FOCUS: 'focus', KEYDOWN: 'keydown', KEYPRESS: 'keypress', LOAD: 'load', diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index 3c42f72451..7f9f81d8ca 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -662,6 +662,21 @@ describe('ol.Map', function() { expect(map.handleResize_).to.be.ok(); }); + it('handles touch-action on focus and blur', function() { + expect(map.focusHandlerKeys_).to.be(null); + expect(map.getViewport().getAttribute('touch-action')).to.be('none'); + const target = document.createElement('div'); + target.setAttribute('tabindex', 1); + map.setTarget(target); + expect(Array.isArray(map.focusHandlerKeys_)).to.be(true); + expect(map.getViewport().getAttribute('touch-action')).to.be('auto'); + target.dispatchEvent(new Event('focus')); + expect(map.getViewport().getAttribute('touch-action')).to.be('none'); + map.setTarget(null); + expect(map.focusHandlerKeys_).to.be(null); + expect(map.getViewport().getAttribute('touch-action')).to.be('none'); + }); + describe('call setTarget with null', function() { it('unregisters the viewport resize listener', function() { map.setTarget(null);