Skip to content

Commit f47301f

Browse files
committed
It prevent event if user tries to perform vertical scroll in an horizontal scrolling element
1 parent 36f3a19 commit f47301f

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

src/utils/scroll-lock.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
let isLocked = false;
1212
let initialClientY = -1;
13+
let initialClientX = -1;
1314
let scrolledClientY = 0;
1415
// Adds this attribute to an inner scrollable element to allow it to scroll
1516
export const SCROLL_LOCK_DISABLE_ATTR = 'data-scroll-lock-disable';
@@ -82,8 +83,10 @@ const isVerticalScroll = ({ scrollHeight, scrollWidth }) => scrollHeight > scrol
8283
* @return {boolean}
8384
*/
8485
function handleScroll(event, target) {
86+
const clientY = event.targetTouches[0].clientY - initialClientY;
87+
const clientX = event.targetTouches[0].clientX - initialClientX;
88+
8589
if (isVerticalScroll(target)) {
86-
const clientY = event.targetTouches[0].clientY - initialClientY;
8790
if (target.scrollTop === 0 && clientY > 0) {
8891
// element is at the top of its scroll.
8992
return preventDefault(event);
@@ -93,6 +96,9 @@ function handleScroll(event, target) {
9396
// element is at the bottom of its scroll.
9497
return preventDefault(event);
9598
}
99+
} else if (Math.abs(clientY) > Math.abs(clientX)) {
100+
// prevent event if user tries to perform vertical scroll in an horizontal scrolling element
101+
return preventDefault(event);
96102
}
97103

98104
// prevent the scroll event from going up to the parent/window
@@ -114,6 +120,7 @@ function advancedLock(targetElement) {
114120
if (event.targetTouches.length === 1) {
115121
// detect single touch.
116122
initialClientY = event.targetTouches[0].clientY;
123+
initialClientX = event.targetTouches[0].clientX;
117124
}
118125
};
119126
targetElement.ontouchmove = (event) => {

tests/unit/utils/scroll-lock.spec.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,30 @@ describe('scroll-lock', () => {
101101
expect(disabledTarget.ontouchstart).toBeFalsy();
102102
});
103103

104+
it('prevent event if user tries to perform vertical scroll in an horizontal scrolling element', () => {
105+
Object.defineProperty(container, 'scrollWidth', { value: 100, writable: true });
106+
107+
const touchStartEvent = {
108+
targetTouches: [{ clientY: 0, clientX: 0 }],
109+
};
110+
const touchMoveEvent = {
111+
targetTouches: [{ clientY: -10, clientX: 0 }],
112+
preventDefault,
113+
stopPropagation,
114+
touches: [1],
115+
target: {
116+
closest: jest.fn(),
117+
},
118+
};
119+
120+
scrollLock.lockScroll(container);
121+
container.ontouchstart(touchStartEvent);
122+
container.ontouchmove(touchMoveEvent);
123+
124+
expect(preventDefault).toHaveBeenCalledTimes(1);
125+
expect(stopPropagation).toHaveBeenCalledTimes(0);
126+
});
127+
104128
it('prevents body scrolling', () => {
105129
scrollLock.lockScroll(container);
106130
// assert body scroll is getting prevented when swiping up/down

0 commit comments

Comments
 (0)