From 3d336c1523d547e3003cd2e0014750a30f821092 Mon Sep 17 00:00:00 2001 From: Feoktist Shovchko Date: Fri, 1 Dec 2023 22:47:53 +0200 Subject: [PATCH 1/4] chore(esl-event-listener): block scroll --- .../esl-swipe-demo/esl-swipe-demo-area.ts | 19 ++++++++++ .../esl-wheel-demo/esl-wheel-demo-area.ts | 19 ++++++++++ .../src/esl-events-demo/log-area/log-area.ts | 26 ++++++++++++++ pages/views/draft/wheel-demo.njk | 31 ++++++++++++++++ .../core/targets/swipe.target.ts | 11 ++++++ .../core/targets/wheel.target.ts | 12 +++++++ src/modules/esl-utils/dom/scroll/parent.ts | 32 +++++++++-------- .../esl-utils/dom/scroll/test/parent.test.ts | 36 +++++++++++++++++++ src/modules/esl-utils/dom/scroll/utils.ts | 16 ++++++++- 9 files changed, 187 insertions(+), 15 deletions(-) create mode 100644 pages/src/esl-events-demo/esl-swipe-demo/esl-swipe-demo-area.ts create mode 100644 pages/src/esl-events-demo/esl-wheel-demo/esl-wheel-demo-area.ts create mode 100644 pages/src/esl-events-demo/log-area/log-area.ts create mode 100644 pages/views/draft/wheel-demo.njk diff --git a/pages/src/esl-events-demo/esl-swipe-demo/esl-swipe-demo-area.ts b/pages/src/esl-events-demo/esl-swipe-demo/esl-swipe-demo-area.ts new file mode 100644 index 000000000..197ccc35a --- /dev/null +++ b/pages/src/esl-events-demo/esl-swipe-demo/esl-swipe-demo-area.ts @@ -0,0 +1,19 @@ +import {ESLSwipeGestureTarget, ESLSwipeGestureEvent} from '@exadel/esl/modules/esl-event-listener/core'; +import {listen} from '@exadel/esl/modules/esl-utils/decorators'; + +import {ESLDemoLogArea} from '../log-area/log-area'; + +/** Area element for logging swipe event data */ +export class ESLDemoSwipeArea extends ESLDemoLogArea { + static override is = 'esl-d-swipe-area'; + + @listen({ + event: 'swipe', + target: ESLSwipeGestureTarget.for + }) + onSwipe(e: ESLSwipeGestureEvent): void { + const {name} = ESLSwipeGestureEvent; + const {type, direction, distanceX, distanceY, distance, angle} = e; + this.log({name, type, data: {direction, distanceX, distanceY, distance, angle}}); + } +} diff --git a/pages/src/esl-events-demo/esl-wheel-demo/esl-wheel-demo-area.ts b/pages/src/esl-events-demo/esl-wheel-demo/esl-wheel-demo-area.ts new file mode 100644 index 000000000..3d0d7c225 --- /dev/null +++ b/pages/src/esl-events-demo/esl-wheel-demo/esl-wheel-demo-area.ts @@ -0,0 +1,19 @@ +import {ESLWheelTarget, ESLWheelEvent} from '@exadel/esl/modules/esl-event-listener/core'; +import {listen} from '@exadel/esl/modules/esl-utils/decorators'; + +import {ESLDemoLogArea} from '../log-area/log-area'; + +/** Area element for logging long wheel event data */ +export class ESLDemoWheelArea extends ESLDemoLogArea { + static override is = 'esl-d-wheel-area'; + + @listen({ + event: 'longwheel', + target: ESLWheelTarget.for + }) + onWheel(e: ESLWheelEvent): void { + const {name} = ESLWheelEvent; + const {type, axis, deltaX, deltaY} = e; + this.log({name, type, data: {axis, deltaX, deltaY}}); + } +} diff --git a/pages/src/esl-events-demo/log-area/log-area.ts b/pages/src/esl-events-demo/log-area/log-area.ts new file mode 100644 index 000000000..26ea42abc --- /dev/null +++ b/pages/src/esl-events-demo/log-area/log-area.ts @@ -0,0 +1,26 @@ +import {ESLBaseElement} from '@exadel/esl/modules/esl-base-element/core'; + +export interface LogEventData { + /** The name of the event's class */ + name: string; + /** The type of the event */ + type: string; + /** Additional event data */ + data: Record; +} + +/** Base element for logging event data */ +export class ESLDemoLogArea extends ESLBaseElement { + static override is = 'esl-d-logger'; + + log(eventData: LogEventData): void { + const {name, type, data} = eventData; + const $logItem = document.createElement('div'); + $logItem.className = 'log-item'; + $logItem.innerHTML = `${name} ( ${type} ): {${Object.entries(data).map(([key, value]) => `${key}: ${value}`).join(', ')}}`; + this.appendChild($logItem); + this.scrollTo({top: this.scrollHeight, behavior: 'smooth'}); + setTimeout(() => $logItem.classList.add('removed'), 2500); + setTimeout(() => $logItem.remove(), 3000); + } +} diff --git a/pages/views/draft/wheel-demo.njk b/pages/views/draft/wheel-demo.njk new file mode 100644 index 000000000..b5ed5fb3d --- /dev/null +++ b/pages/views/draft/wheel-demo.njk @@ -0,0 +1,31 @@ +--- +layout: content +title: Long Wheel Event Target (Regression) +name: Long Wheel Event Target (Regression) +tags: [draft] +--- + +
+
+

+ ESLWheelTarget usage example +

+ {% code 'ts', 'code-block' %} + @listen({ + event: 'longwheel', + target: ESLWheelTarget.for + }) + onWheel(e: ESLWheelEvent): void { + const $logItem = document.createElement('div'); + $logItem.className = 'log-item'; + $logItem.textContent = JSON.stringify(e); + this.appendChild($logItem); + } + {% endcode %} + +
+ +
+ +
+
diff --git a/src/modules/esl-event-listener/core/targets/swipe.target.ts b/src/modules/esl-event-listener/core/targets/swipe.target.ts index 35efeef4b..245d65d8b 100644 --- a/src/modules/esl-event-listener/core/targets/swipe.target.ts +++ b/src/modules/esl-event-listener/core/targets/swipe.target.ts @@ -1,4 +1,5 @@ import {SyntheticEventTarget} from '../../../esl-utils/dom/events/target'; +import {getParentScrollOffsets, isOffsetChanged} from '../../../esl-utils/dom/scroll'; import {getTouchPoint, isMouseEvent, isTouchEvent} from '../../../esl-utils/dom/events/misc'; import {resolveDomTarget} from '../../../esl-utils/abstract/dom-target'; import {isElement} from '../../../esl-utils/dom/api'; @@ -7,6 +8,7 @@ import {resolveCSSSize} from '../../../esl-utils/dom/units'; import {ESLEventListener} from '../listener'; import {ESLSwipeGestureEvent} from './swipe.target.event'; +import type {ElementScrollOffset} from '../../../esl-utils/dom//scroll'; import type {CSSSize} from '../../../esl-utils/dom/units'; import type {SwipeDirection, SwipeEventName, ESLSwipeGestureEventInfo} from './swipe.target.event'; import type {ESLDomElementTarget} from '../../../esl-utils/abstract/dom-target'; @@ -17,6 +19,8 @@ export {ESLSwipeGestureEvent}; * Describes settings object that could be passed to {@link ESLSwipeGestureTarget.for} as optional parameter */ export interface ESLSwipeGestureSetting { + /** Flag to indicate if long event should be dispatched if scroll of content was detected (true by default) */ + processOverflow?: boolean; /** The minimum distance to accept swipe (supports `px`, `vw` and `vh` units) */ threshold?: CSSSize; /** The maximum duration between `ponterdown` and `pointerup` events */ @@ -28,6 +32,7 @@ export interface ESLSwipeGestureSetting { */ export class ESLSwipeGestureTarget extends SyntheticEventTarget { protected static defaultConfig: Required = { + processOverflow: true, threshold: '20px', timeout: 500 }; @@ -49,6 +54,7 @@ export class ESLSwipeGestureTarget extends SyntheticEventTarget { protected readonly config: Required; protected startEvent: PointerEvent; + protected startEventOffset: ElementScrollOffset[]; protected constructor( protected readonly target: Element, @@ -70,6 +76,7 @@ export class ESLSwipeGestureTarget extends SyntheticEventTarget { * @param startEvent - initial pointer event */ protected handleStart(startEvent: PointerEvent): void { + this.startEventOffset = this.config.processOverflow ? [] : getParentScrollOffsets(startEvent.target as Element, this.target); this.startEvent = startEvent; ESLEventListener.subscribe(this, this.handleEnd, { event: this.endEventName, @@ -119,6 +126,10 @@ export class ESLSwipeGestureTarget extends SyntheticEventTarget { // return if swipe took too long or distance is too short if (!this.isGestureAcceptable(eventDetails)) return; + if (!this.config.processOverflow) { + const offsets = getParentScrollOffsets(endEvent.target as Element, this.target); + if (isOffsetChanged(this.startEventOffset.concat(offsets))) return; + } const event = ESLSwipeGestureEvent.fromConfig('swipe', this.target, eventDetails); // fire `swipe` event on the element that started the swipe diff --git a/src/modules/esl-event-listener/core/targets/wheel.target.ts b/src/modules/esl-event-listener/core/targets/wheel.target.ts index ee065bc27..c18ffb952 100644 --- a/src/modules/esl-event-listener/core/targets/wheel.target.ts +++ b/src/modules/esl-event-listener/core/targets/wheel.target.ts @@ -1,5 +1,6 @@ import {SyntheticEventTarget} from '../../../esl-utils/dom/events/target'; import {resolveDomTarget} from '../../../esl-utils/abstract/dom-target'; +import {getParentScrollOffsets, isOffsetChanged} from '../../../esl-utils/dom/scroll'; import {isElement} from '../../../esl-utils/dom/api'; import {bind} from '../../../esl-utils/decorators/bind'; import {aggregate} from '../../../esl-utils/async/aggregate'; @@ -9,6 +10,7 @@ import {ESLWheelEvent} from './wheel.target.event'; import type {ESLWheelEventInfo} from './wheel.target.event'; import type {ESLDomElementTarget} from '../../../esl-utils/abstract/dom-target'; +import type {ElementScrollOffset} from '../../../esl-utils/dom/scroll'; export {ESLWheelEvent}; @@ -16,6 +18,8 @@ export {ESLWheelEvent}; * Describes settings object that could be passed to {@link ESLWheelTarget.for} as optional parameter */ export interface ESLWheelTargetSetting { + /** Flag to indicate if long event should be dispatched if scroll of content was detected (false by default) */ + processOverflow?: boolean; /** The minimum distance to accept as a long scroll */ distance?: number; /** The maximum duration of the wheel events to consider it inertial */ @@ -27,12 +31,15 @@ export interface ESLWheelTargetSetting { */ export class ESLWheelTarget extends SyntheticEventTarget { protected static defaultConfig: Required = { + processOverflow: true, distance: 400, timeout: 100 }; protected readonly config: Required; + protected scrollData: ElementScrollOffset[] = []; + /** Function for aggregating wheel events into array of events */ protected aggregateWheel: (event: WheelEvent) => void; @@ -63,12 +70,17 @@ export class ESLWheelTarget extends SyntheticEventTarget { /** Handles wheel events */ @bind protected _onWheel(event: WheelEvent): void { + if (!this.config.processOverflow) this.scrollData = this.scrollData.concat(getParentScrollOffsets(event.target as Element, this.target)); this.aggregateWheel(event); } /** Handles aggregated wheel events */ protected handleAggregatedWheel(events: WheelEvent[]): void { const wheelInfo = this.resolveEventDetails(events); + + const isBlocked = isOffsetChanged(this.scrollData); + this.scrollData = []; + if (isBlocked) return; if (Math.abs(wheelInfo.deltaX) >= this.config.distance) this.dispatchWheelEvent('x', wheelInfo); if (Math.abs(wheelInfo.deltaY) >= this.config.distance) this.dispatchWheelEvent('y', wheelInfo); } diff --git a/src/modules/esl-utils/dom/scroll/parent.ts b/src/modules/esl-utils/dom/scroll/parent.ts index 7010fcf2f..dce592d9a 100644 --- a/src/modules/esl-utils/dom/scroll/parent.ts +++ b/src/modules/esl-utils/dom/scroll/parent.ts @@ -3,32 +3,36 @@ import {isElement, getNodeName, getParentNode} from '../api'; /** * Get the list of all scroll parents, up the list of ancestors until we get to the top window object. * @param element - element for which you want to get the list of all scroll parents - * @param list - array of elements to concatenate with the list of all scroll parents of element (optional) + * @param topElement - element which element considered a final scrollable parent target (optional, defaults to element.ownerDocument?.body) */ -export function getListScrollParents(element: Element, list: Element[] = []): Element[] { - const scrollParent = getScrollParent(element); - const isBody = scrollParent === element.ownerDocument?.body; - const target = isBody - ? isScrollable(scrollParent) ? scrollParent : [] - : scrollParent; - - const updatedList = list.concat(target); - return isBody - ? updatedList - : updatedList.concat(getListScrollParents(getParentNode(scrollParent) as Element)); +export function getListScrollParents(element: Element, topElement?: Element): Element[] { + const targetParent = topElement || element.ownerDocument?.body; + const scrollParent = getScrollParent(element, targetParent); + if (!scrollParent) return []; + const isScrollableTarget = scrollParent === targetParent; + if (isScrollableTarget) return isScrollable(scrollParent) ? [scrollParent] : []; + return [scrollParent].concat(getListScrollParents(getParentNode(scrollParent) as Element, targetParent)); } +/** + * Get the scroll parent of the specified element in the DOM tree. + * @param node - element for which to get the scroll parent + * @param topElement - element which element considered a final scrollable parent + */ +export function getScrollParent(node: Element, topElement: Element): Element | undefined; /** * Get the scroll parent of the specified element in the DOM tree. * @param node - element for which to get the scroll parent */ -export function getScrollParent(node: Element): Element { +export function getScrollParent(node: Element): Element; +export function getScrollParent(node: Element, topElement?: Element): Element | undefined { if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { return node.ownerDocument?.body as Element; } if (isElement(node) && isScrollable(node)) return node; - return getScrollParent(getParentNode(node) as Element); + if (node === topElement) return; + return getScrollParent(getParentNode(node) as Element, topElement!); } /** diff --git a/src/modules/esl-utils/dom/scroll/test/parent.test.ts b/src/modules/esl-utils/dom/scroll/test/parent.test.ts index 78c81edb2..c87ca6bc5 100644 --- a/src/modules/esl-utils/dom/scroll/test/parent.test.ts +++ b/src/modules/esl-utils/dom/scroll/test/parent.test.ts @@ -86,6 +86,27 @@ describe('Function getScrollParent', () => { expect(getScrollParent(thirdLevelChild)).toEqual(target); }); }); + + describe('Limit search to top target element', () => { + const firstLevelChild = document.createElement('div'); + target.appendChild(firstLevelChild); + + firstLevelChild.style.overflow = 'auto'; + + beforeAll(() => target.style.overflow = ''); + + test('should detect first scrollable parent element', () => { + expect(getScrollParent(firstLevelChild, target)).toEqual(firstLevelChild); + }); + + test('should accept body element as top target element', () => { + expect(getScrollParent(target, $body)).toEqual($body); + }); + + test('should return undefined if any scrollable parents found', () => { + expect(getScrollParent(target, target)).toEqual(undefined); + }); + }); }); describe('Function getListScrollParents', () => { @@ -120,4 +141,19 @@ describe('Function getListScrollParents', () => { expect(getListScrollParents(thirdLevelChild)).toEqual([thirdLevelChild, firstLevelChild, $body]); }); + + test('target should only detect scrollable elements up to top target element', () => { + const firstLevelChild = document.createElement('div'); + const secondLevelChild = document.createElement('div'); + const thirdLevelChild = document.createElement('div'); + + firstLevelChild.style.overflow = 'auto'; + thirdLevelChild.style.overflow = 'auto'; + + secondLevelChild.appendChild(thirdLevelChild); + target.appendChild(firstLevelChild); + firstLevelChild.appendChild(secondLevelChild); + + expect(getListScrollParents(thirdLevelChild, secondLevelChild)).toEqual([thirdLevelChild]); + }); }); diff --git a/src/modules/esl-utils/dom/scroll/utils.ts b/src/modules/esl-utils/dom/scroll/utils.ts index 35401b5d5..be31ae2c8 100644 --- a/src/modules/esl-utils/dom/scroll/utils.ts +++ b/src/modules/esl-utils/dom/scroll/utils.ts @@ -1,4 +1,4 @@ -import {getScrollParent} from './parent'; +import {getListScrollParents, getScrollParent} from './parent'; const $html = document.documentElement; @@ -82,3 +82,17 @@ export function unlockScroll(target: Element = $html, options: ScrollLockOptions scrollable.removeAttribute('esl-scroll-lock'); if (options.recursive && scrollable.parentElement) unlockScroll(scrollable.parentElement, options); } + +export interface ElementScrollOffset { + element: Element; + top: number; + left: number; +} + +export function isOffsetChanged(offsets: ElementScrollOffset[]): boolean { + return offsets.some((element) => element.element.scrollTop !== element.top || element.element.scrollLeft !== element.left); +} + +export function getParentScrollOffsets($el: Element, $topContainer: Element): ElementScrollOffset[] { + return getListScrollParents($el, $topContainer).map((el) => ({element: el, top: el.scrollTop, left: el.scrollLeft})); +} From 66ebfe0c56a80a08690a17f0e8b679378714b3f6 Mon Sep 17 00:00:00 2001 From: Feoktist Shovchko Date: Fri, 26 Jan 2024 17:30:38 +0200 Subject: [PATCH 2/4] chore(esl-event-listener): code refactoring --- .../core/targets/swipe.target.ts | 10 ++++----- .../core/targets/wheel.target.ts | 8 +++---- src/modules/esl-utils/dom/scroll/parent.ts | 22 +++++++++---------- 3 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/modules/esl-event-listener/core/targets/swipe.target.ts b/src/modules/esl-event-listener/core/targets/swipe.target.ts index 7ef31f9a3..1e2aa493a 100644 --- a/src/modules/esl-event-listener/core/targets/swipe.target.ts +++ b/src/modules/esl-event-listener/core/targets/swipe.target.ts @@ -19,8 +19,8 @@ export {ESLSwipeGestureEvent}; * Describes settings object that could be passed to {@link ESLSwipeGestureTarget.for} as optional parameter */ export interface ESLSwipeGestureSetting { - /** Flag to indicate if long event should be dispatched if scroll of content was detected (true by default) */ - processOverflow?: boolean; + /** Flag to indicate if the swipe event should not be dispatched if a scroll of content was detected (true by default) */ + skipOnScroll?: boolean; /** The minimum distance to accept swipe (supports `px`, `vw` and `vh` units) */ threshold?: CSSSize; /** The maximum duration between `ponterdown` and `pointerup` events */ @@ -32,7 +32,7 @@ export interface ESLSwipeGestureSetting { */ export class ESLSwipeGestureTarget extends SyntheticEventTarget { protected static defaultConfig: Required = { - processOverflow: true, + skipOnScroll: true, threshold: '20px', timeout: 500 }; @@ -76,7 +76,7 @@ export class ESLSwipeGestureTarget extends SyntheticEventTarget { * @param startEvent - initial pointer event */ protected handleStart(startEvent: PointerEvent): void { - this.startEventOffset = this.config.processOverflow ? [] : getParentScrollOffsets(startEvent.target as Element, this.target); + this.startEventOffset = this.config.skipOnScroll ? getParentScrollOffsets(startEvent.target as Element, this.target) : []; this.startEvent = startEvent; ESLEventListener.subscribe(this, this.handleEnd, { event: this.endEventName, @@ -126,7 +126,7 @@ export class ESLSwipeGestureTarget extends SyntheticEventTarget { // return if swipe took too long or distance is too short if (!this.isGestureAcceptable(eventDetails)) return; - if (!this.config.processOverflow) { + if (this.config.skipOnScroll) { const offsets = getParentScrollOffsets(endEvent.target as Element, this.target); if (isOffsetChanged(this.startEventOffset.concat(offsets))) return; } diff --git a/src/modules/esl-event-listener/core/targets/wheel.target.ts b/src/modules/esl-event-listener/core/targets/wheel.target.ts index 558c10618..cac6bf0e5 100644 --- a/src/modules/esl-event-listener/core/targets/wheel.target.ts +++ b/src/modules/esl-event-listener/core/targets/wheel.target.ts @@ -18,8 +18,8 @@ export {ESLWheelEvent}; * Describes settings object that could be passed to {@link ESLWheelTarget.for} as optional parameter */ export interface ESLWheelTargetSetting { - /** Flag to indicate if long event should be dispatched if scroll of content was detected (false by default) */ - processOverflow?: boolean; + /** Flag to indicate if the `longwheel` event shouldn't be dispatched if scroll of content was detected (false by default) */ + skipOnScroll?: boolean; /** The minimum distance to accept as a long scroll */ distance?: number; /** The maximum duration of the wheel events to consider it inertial */ @@ -31,7 +31,7 @@ export interface ESLWheelTargetSetting { */ export class ESLWheelTarget extends SyntheticEventTarget { protected static defaultConfig: Required = { - processOverflow: true, + skipOnScroll: true, distance: 400, timeout: 100 }; @@ -70,7 +70,7 @@ export class ESLWheelTarget extends SyntheticEventTarget { /** Handles wheel events */ @bind protected _onWheel(event: WheelEvent): void { - if (!this.config.processOverflow) this.scrollData = this.scrollData.concat(getParentScrollOffsets(event.target as Element, this.target)); + if (this.config.skipOnScroll) this.scrollData = this.scrollData.concat(getParentScrollOffsets(event.target as Element, this.target)); this.aggregateWheel(event); } diff --git a/src/modules/esl-utils/dom/scroll/parent.ts b/src/modules/esl-utils/dom/scroll/parent.ts index dce592d9a..0d97a9829 100644 --- a/src/modules/esl-utils/dom/scroll/parent.ts +++ b/src/modules/esl-utils/dom/scroll/parent.ts @@ -3,36 +3,36 @@ import {isElement, getNodeName, getParentNode} from '../api'; /** * Get the list of all scroll parents, up the list of ancestors until we get to the top window object. * @param element - element for which you want to get the list of all scroll parents - * @param topElement - element which element considered a final scrollable parent target (optional, defaults to element.ownerDocument?.body) + * @param root - element which element considered a final scrollable parent target (optional, defaults to element.ownerDocument?.body) */ -export function getListScrollParents(element: Element, topElement?: Element): Element[] { - const targetParent = topElement || element.ownerDocument?.body; - const scrollParent = getScrollParent(element, targetParent); +export function getListScrollParents(element: Element, root?: Element): Element[] { + const limitNode = root || element.ownerDocument?.body; + const scrollParent = getScrollParent(element, limitNode); if (!scrollParent) return []; - const isScrollableTarget = scrollParent === targetParent; + const isScrollableTarget = scrollParent === limitNode; if (isScrollableTarget) return isScrollable(scrollParent) ? [scrollParent] : []; - return [scrollParent].concat(getListScrollParents(getParentNode(scrollParent) as Element, targetParent)); + return [scrollParent].concat(getListScrollParents(getParentNode(scrollParent) as Element, limitNode)); } /** * Get the scroll parent of the specified element in the DOM tree. * @param node - element for which to get the scroll parent - * @param topElement - element which element considered a final scrollable parent + * @param root - element which element considered a final scrollable parent */ -export function getScrollParent(node: Element, topElement: Element): Element | undefined; +export function getScrollParent(node: Element, root: Element): Element | undefined; /** * Get the scroll parent of the specified element in the DOM tree. * @param node - element for which to get the scroll parent */ export function getScrollParent(node: Element): Element; -export function getScrollParent(node: Element, topElement?: Element): Element | undefined { +export function getScrollParent(node: Element, root?: Element): Element | undefined { if (['html', 'body', '#document'].indexOf(getNodeName(node)) >= 0) { return node.ownerDocument?.body as Element; } if (isElement(node) && isScrollable(node)) return node; - if (node === topElement) return; - return getScrollParent(getParentNode(node) as Element, topElement!); + if (node === root) return; + return getScrollParent(getParentNode(node) as Element, root!); } /** From ed82c0c0c1dec39f0abec32e8712d29781c374fe Mon Sep 17 00:00:00 2001 From: "ala'n (Alexey Stsefanovich)" Date: Mon, 29 Jan 2024 15:59:05 +0100 Subject: [PATCH 3/4] style(esl-event-listener): simplify `wheel.target.ts` implementation Co-authored-by: Dmytro Shovchko --- src/modules/esl-event-listener/core/targets/wheel.target.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/modules/esl-event-listener/core/targets/wheel.target.ts b/src/modules/esl-event-listener/core/targets/wheel.target.ts index cac6bf0e5..b27c3fe95 100644 --- a/src/modules/esl-event-listener/core/targets/wheel.target.ts +++ b/src/modules/esl-event-listener/core/targets/wheel.target.ts @@ -70,7 +70,10 @@ export class ESLWheelTarget extends SyntheticEventTarget { /** Handles wheel events */ @bind protected _onWheel(event: WheelEvent): void { - if (this.config.skipOnScroll) this.scrollData = this.scrollData.concat(getParentScrollOffsets(event.target as Element, this.target)); + if (this.config.skipOnScroll) { + const offsets = getParentScrollOffsets(event.target as Element, this.target); + this.scrollData = this.scrollData.concat(offsets); + } this.aggregateWheel(event); } From 533674d269a0b897690d17dd55f007e0e6f1962a Mon Sep 17 00:00:00 2001 From: "ala'n (Alexey Stsefanovich)" Date: Mon, 29 Jan 2024 15:59:50 +0100 Subject: [PATCH 4/4] docs(esl-event-listener): fix `wheel.target.ts` JS doc defaults Co-authored-by: Anna Barmina <52083788+abarmina@users.noreply.github.com> --- src/modules/esl-event-listener/core/targets/wheel.target.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/esl-event-listener/core/targets/wheel.target.ts b/src/modules/esl-event-listener/core/targets/wheel.target.ts index b27c3fe95..5820d82f6 100644 --- a/src/modules/esl-event-listener/core/targets/wheel.target.ts +++ b/src/modules/esl-event-listener/core/targets/wheel.target.ts @@ -18,7 +18,7 @@ export {ESLWheelEvent}; * Describes settings object that could be passed to {@link ESLWheelTarget.for} as optional parameter */ export interface ESLWheelTargetSetting { - /** Flag to indicate if the `longwheel` event shouldn't be dispatched if scroll of content was detected (false by default) */ + /** Flag to indicate if the `longwheel` event shouldn't be dispatched if scroll of content was detected (true by default) */ skipOnScroll?: boolean; /** The minimum distance to accept as a long scroll */ distance?: number;