diff --git a/src/google_map.js b/src/google_map.js index dc525a7..180ff6a 100644 --- a/src/google_map.js +++ b/src/google_map.js @@ -26,6 +26,7 @@ import shallowEqual from './utils/shallowEqual'; import isPlainObject from './utils/isPlainObject'; import isArraysEqualEps from './utils/isArraysEqualEps'; import detectElementResize from './utils/detectElementResize'; +import addPassiveEventListener from './utils/passiveEvents'; // consts const kEPS = 0.00001; @@ -245,17 +246,22 @@ export default class GoogleMap extends Component { componentDidMount() { this.mounted_ = true; - window.addEventListener('resize', this._onWindowResize); - window.addEventListener('keydown', this._onKeyDownCapture, true); + addPassiveEventListener(window, 'resize', this._onWindowResize, false); + addPassiveEventListener(window, 'keydown', this._onKeyDownCapture, true); const mapDom = ReactDOM.findDOMNode(this.googleMapDom_); // gmap can't prevent map drag if mousedown event already occured // the only workaround I find is prevent mousedown native browser event if (mapDom) { - mapDom.addEventListener('mousedown', this._onMapMouseDownNative, true); + addPassiveEventListener( + mapDom, + 'mousedown', + this._onMapMouseDownNative, + true + ); } - window.addEventListener('mouseup', this._onChildMouseUp, false); + addPassiveEventListener(window, 'mouseup', this._onChildMouseUp, false); const bootstrapURLKeys = { ...(this.props.apiKey && { key: this.props.apiKey }), ...this.props.bootstrapURLKeys, diff --git a/src/utils/detectElementResize.js b/src/utils/detectElementResize.js index 7ad2673..2b67607 100644 --- a/src/utils/detectElementResize.js +++ b/src/utils/detectElementResize.js @@ -9,6 +9,8 @@ * version: 0.5.3 **/ +import addPassiveEventListener from './passiveEvents'; + // Reliable `window` and `document` detection var canUseDOM = !!(typeof window !== 'undefined' && window.document && @@ -171,7 +173,8 @@ var addResizeListener = function(element, fn) { '
'; element.appendChild(element.__resizeTriggers__); resetTriggers(element); - element.addEventListener('scroll', scrollListener, true); + + addPassiveEventListener(element, 'scroll', scrollListener, true); /* Listen for a css animation to detect element display/re-attach */ animationstartevent && diff --git a/src/utils/passiveEvents.js b/src/utils/passiveEvents.js new file mode 100644 index 0000000..6b0ed7e --- /dev/null +++ b/src/utils/passiveEvents.js @@ -0,0 +1,38 @@ +// feature detection for passive support +// see: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support +function hasPassiveSupport() { + let passiveSupported = false; + + try { + const options = Object.defineProperty({}, 'passive', { + get() { + passiveSupported = true; + }, + }); + + window.addEventListener('test', options, options); + window.removeEventListener('test', options, options); + } catch (err) { + passiveSupported = false; + } + + return passiveSupported; +} + +export default function addPassiveEventListener( + element, + eventName, + func, + capture +) { + element.addEventListener( + eventName, + func, + hasPassiveSupport() + ? { + capture, + passive: true, + } + : capture + ); +}