From 8d1669b8896d84a67c61d3a00d0b13c42d70f30f Mon Sep 17 00:00:00 2001 From: tanjinzhou <415800467@qq.com> Date: Thu, 10 Dec 2020 17:40:46 +0800 Subject: [PATCH] fix: passive waring --- components/_util/supportsPassive.js | 13 ++++++ components/affix/utils.ts | 12 ++++-- components/vc-drawer/src/Drawer.js | 14 +------ components/vc-trigger/Trigger.jsx | 10 +++-- components/vc-util/Dom/addEventListener.js | 12 +++++- components/vc-virtual-list/List.tsx | 13 +++++- components/vc-virtual-list/ScrollBar.tsx | 37 ++++++++++++++--- .../hooks/useMobileTouchMove.ts | 41 +++++++++++++++++-- 8 files changed, 121 insertions(+), 31 deletions(-) create mode 100644 components/_util/supportsPassive.js diff --git a/components/_util/supportsPassive.js b/components/_util/supportsPassive.js new file mode 100644 index 000000000..34722aa12 --- /dev/null +++ b/components/_util/supportsPassive.js @@ -0,0 +1,13 @@ +// Test via a getter in the options object to see if the passive property is accessed +let supportsPassive = false; +try { + let opts = Object.defineProperty({}, 'passive', { + get() { + supportsPassive = true; + }, + }); + window.addEventListener('testPassive', null, opts); + window.removeEventListener('testPassive', null, opts); +} catch (e) {} + +export default supportsPassive; diff --git a/components/affix/utils.ts b/components/affix/utils.ts index 898f8d68d..d1b7bd373 100644 --- a/components/affix/utils.ts +++ b/components/affix/utils.ts @@ -1,5 +1,6 @@ import addEventListener from '../vc-util/Dom/addEventListener'; import { ComponentPublicInstance } from 'vue'; +import supportsPassive from '../_util/supportsPassive'; export type BindElement = HTMLElement | Window | null | undefined; export type Rect = ClientRect | DOMRect; @@ -78,9 +79,14 @@ export function addObserveTarget( // Add listener TRIGGER_EVENTS.forEach(eventName => { entity!.eventHandlers[eventName] = addEventListener(target, eventName, () => { - entity!.affixList.forEach(targetAffix => { - (targetAffix as any).lazyUpdatePosition(); - }); + entity!.affixList.forEach( + targetAffix => { + (targetAffix as any).lazyUpdatePosition(); + }, + (eventName === 'touchstart' || eventName === 'touchmove') && supportsPassive + ? ({ passive: true } as EventListenerOptions) + : false, + ); }); }); } diff --git a/components/vc-drawer/src/Drawer.js b/components/vc-drawer/src/Drawer.js index b6e0ed431..d98db7701 100644 --- a/components/vc-drawer/src/Drawer.js +++ b/components/vc-drawer/src/Drawer.js @@ -14,6 +14,7 @@ import { transformArguments, isNumeric, } from './utils'; +import supportsPassive from '../../_util/supportsPassive'; function noop() {} @@ -100,18 +101,7 @@ const Drawer = defineComponent({ mounted() { nextTick(() => { if (!windowIsUndefined) { - let passiveSupported = false; - window.addEventListener( - 'test', - null, - Object.defineProperty({}, 'passive', { - get: () => { - passiveSupported = true; - return null; - }, - }), - ); - this.passive = passiveSupported ? { passive: false } : false; + this.passive = supportsPassive ? { passive: false } : false; } const open = this.getOpen(); if (this.handler || open || this.sFirstEnter) { diff --git a/components/vc-trigger/Trigger.jsx b/components/vc-trigger/Trigger.jsx index 6b1f0e3e2..63b49daa1 100644 --- a/components/vc-trigger/Trigger.jsx +++ b/components/vc-trigger/Trigger.jsx @@ -18,6 +18,7 @@ import BaseMixin from '../_util/BaseMixin'; import Portal from '../_util/Portal'; import classNames from '../_util/classNames'; import { cloneElement } from '../_util/vnode'; +import supportsPassive from '../_util/supportsPassive'; function returnEmptyString() { return ''; @@ -165,6 +166,7 @@ export default defineComponent({ currentDocument, 'touchstart', this.onDocumentClick, + supportsPassive ? { passive: true } : false, ); } // close popup when trigger type contains 'onContextmenu' and document is scrolling. @@ -378,7 +380,7 @@ export default defineComponent({ mouseProps.onMouseleave = self.onPopupMouseleave; } mouseProps.onMousedown = this.onPopupMouseDown; - mouseProps.onTouchstart = this.onPopupMouseDown; + mouseProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onPopupMouseDown; const { handleGetPopupClassFromAlign, getRootDomNode, getContainer, $attrs } = self; const { prefixCls, @@ -603,11 +605,13 @@ export default defineComponent({ if (this.isClickToHide() || this.isClickToShow()) { newChildProps.onClick = this.onClick; newChildProps.onMousedown = this.onMousedown; - newChildProps.onTouchstart = this.onTouchstart; + newChildProps[supportsPassive ? 'onTouchstartPassive' : 'onTouchstart'] = this.onTouchstart; } else { newChildProps.onClick = this.createTwoChains('onClick'); newChildProps.onMousedown = this.createTwoChains('onMousedown'); - newChildProps.onTouchstart = this.createTwoChains('onTouchstart'); + newChildProps[ + supportsPassive ? 'onTouchstartPassive' : 'onTouchstart' + ] = this.createTwoChains('onTouchstart'); } if (this.isMouseEnterToShow()) { newChildProps.onMouseenter = this.onMouseenter; diff --git a/components/vc-util/Dom/addEventListener.js b/components/vc-util/Dom/addEventListener.js index 505252516..71c7c39be 100644 --- a/components/vc-util/Dom/addEventListener.js +++ b/components/vc-util/Dom/addEventListener.js @@ -1,6 +1,16 @@ +import supportsPassive from '../../_util/supportsPassive'; + export default function addEventListenerWrap(target, eventType, cb, option) { if (target.addEventListener) { - target.addEventListener(eventType, cb, option); + let opt = option; + if ( + opt === undefined && + supportsPassive && + (eventType === 'touchstart' || eventType === 'touchmove' || eventType === 'wheel') + ) { + opt = { passive: true }; + } + target.addEventListener(eventType, cb, opt); } return { remove: () => { diff --git a/components/vc-virtual-list/List.tsx b/components/vc-virtual-list/List.tsx index 66062cb18..c62a91ea6 100644 --- a/components/vc-virtual-list/List.tsx +++ b/components/vc-virtual-list/List.tsx @@ -22,6 +22,7 @@ import useOriginScroll from './hooks/useOriginScroll'; import PropTypes from '../_util/vue-types'; import classNames from '../_util/classNames'; import { RenderFunc, SharedConfig } from './interface'; +import supportsPassive from '../_util/supportsPassive'; const EMPTY_DATA = []; @@ -264,7 +265,11 @@ const List = defineComponent({ } const removeEventListener = () => { if (componentRef.value) { - componentRef.value.removeEventListener('wheel', onRawWheel); + componentRef.value.removeEventListener( + 'wheel', + onRawWheel, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); componentRef.value.removeEventListener('DOMMouseScroll', onFireFoxScroll as any); componentRef.value.removeEventListener('MozMousePixelScroll', onMozMousePixelScroll as any); } @@ -273,7 +278,11 @@ const List = defineComponent({ nextTick(() => { if (componentRef.value) { removeEventListener(); - componentRef.value.addEventListener('wheel', onRawWheel); + componentRef.value.addEventListener( + 'wheel', + onRawWheel, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); componentRef.value.addEventListener('DOMMouseScroll', onFireFoxScroll as any); componentRef.value.addEventListener('MozMousePixelScroll', onMozMousePixelScroll as any); } diff --git a/components/vc-virtual-list/ScrollBar.tsx b/components/vc-virtual-list/ScrollBar.tsx index ab96bd8ff..3e8ce9160 100644 --- a/components/vc-virtual-list/ScrollBar.tsx +++ b/components/vc-virtual-list/ScrollBar.tsx @@ -2,6 +2,7 @@ import { defineComponent, PropType, reactive } from 'vue'; import classNames from '../_util/classNames'; import createRef from '../_util/createRef'; import raf from '../_util/raf'; +import supportsPassive from '../_util/supportsPassive'; import PropTypes from '../_util/vue-types'; const MIN_SIZE = 20; @@ -60,8 +61,16 @@ export default defineComponent({ }, mounted() { - this.scrollbarRef.current.addEventListener('touchstart', this.onScrollbarTouchStart); - this.thumbRef.current.addEventListener('touchstart', this.onMouseDown); + this.scrollbarRef.current.addEventListener( + 'touchstart', + this.onScrollbarTouchStart, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); + this.thumbRef.current.addEventListener( + 'touchstart', + this.onMouseDown, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); }, beforeUnmount() { @@ -92,7 +101,11 @@ export default defineComponent({ window.addEventListener('mousemove', this.onMouseMove); window.addEventListener('mouseup', this.onMouseUp); - this.thumbRef.current.addEventListener('touchmove', this.onMouseMove); + this.thumbRef.current.addEventListener( + 'touchmove', + this.onMouseMove, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); this.thumbRef.current.addEventListener('touchend', this.onMouseUp); }, @@ -100,9 +113,21 @@ export default defineComponent({ window.removeEventListener('mousemove', this.onMouseMove); window.removeEventListener('mouseup', this.onMouseUp); - this.scrollbarRef.current.removeEventListener('touchstart', this.onScrollbarTouchStart); - this.thumbRef.current.removeEventListener('touchstart', this.onMouseDown); - this.thumbRef.current.removeEventListener('touchmove', this.onMouseMove); + this.scrollbarRef.current.removeEventListener( + 'touchstart', + this.onScrollbarTouchStart, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); + this.thumbRef.current.removeEventListener( + 'touchstart', + this.onMouseDown, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); + this.thumbRef.current.removeEventListener( + 'touchmove', + this.onMouseMove, + supportsPassive ? ({ passive: true } as EventListenerOptions) : false, + ); this.thumbRef.current.removeEventListener('touchend', this.onMouseUp); raf.cancel(this.moveRaf); diff --git a/components/vc-virtual-list/hooks/useMobileTouchMove.ts b/components/vc-virtual-list/hooks/useMobileTouchMove.ts index d5ff888b3..45ad54435 100644 --- a/components/vc-virtual-list/hooks/useMobileTouchMove.ts +++ b/components/vc-virtual-list/hooks/useMobileTouchMove.ts @@ -1,3 +1,4 @@ +import supportsPassive from '../../_util/supportsPassive'; import { watch, Ref } from 'vue'; const SMOOTH_PTG = 14 / 15; @@ -17,7 +18,15 @@ export default function useMobileTouchMove( const cleanUpEvents = () => { if (element) { - element.removeEventListener('touchmove', onTouchMove); + element.removeEventListener( + 'touchmove', + onTouchMove, + supportsPassive + ? ({ + passive: true, + } as EventListenerOptions) + : false, + ); element.removeEventListener('touchend', onTouchEnd); } }; @@ -58,17 +67,41 @@ export default function useMobileTouchMove( touchY = Math.ceil(e.touches[0].pageY); element = e.target as HTMLElement; - element!.addEventListener('touchmove', onTouchMove); + element!.addEventListener( + 'touchmove', + onTouchMove, + supportsPassive + ? ({ + passive: true, + } as EventListenerOptions) + : false, + ); element!.addEventListener('touchend', onTouchEnd); } }; watch(inVirtual, val => { - listRef.value.removeEventListener('touchstart', onTouchStart); + listRef.value.removeEventListener( + 'touchstart', + onTouchStart, + supportsPassive + ? ({ + passive: true, + } as EventListenerOptions) + : false, + ); cleanUpEvents(); clearInterval(interval); if (val) { - listRef.value.addEventListener('touchstart', onTouchStart); + listRef.value.addEventListener( + 'touchstart', + onTouchStart, + supportsPassive + ? ({ + passive: true, + } as EventListenerOptions) + : false, + ); } }); }