diff --git a/src/components/Filter/FilterInput.vue b/src/components/Filter/FilterInput.vue index 18e747aed..da4d9e6f9 100644 --- a/src/components/Filter/FilterInput.vue +++ b/src/components/Filter/FilterInput.vue @@ -37,7 +37,7 @@
window.navigator && window.navigator.platform @@ -74,19 +76,17 @@ function advancedUnlock(targetElement) { document.removeEventListener('touchmove', preventDefault); } -const isVerticalScroll = ({ scrollHeight, scrollWidth }) => scrollHeight > scrollWidth; - /** * Handles the scrolling of the targetElement * @param {TouchEvent} event * @param {HTMLElement} targetElement * @return {boolean} */ -function handleScroll(event, target) { +function handleScroll(event, target, isHorizontal) { const clientY = event.targetTouches[0].clientY - initialClientY; const clientX = event.targetTouches[0].clientX - initialClientX; - if (isVerticalScroll(target)) { + if (!isHorizontal) { if (target.scrollTop === 0 && clientY > 0) { // element is at the top of its scroll. return preventDefault(event); @@ -110,7 +110,7 @@ function handleScroll(event, target) { * Advanced scroll locking for iOS devices. * @param targetElement */ -function advancedLock(targetElement) { +function advancedLock(targetElement, isHorizontal = false) { // add a scroll listener to the body document.addEventListener('touchmove', preventDefault, { passive: false }); if (!targetElement) return; @@ -126,7 +126,7 @@ function advancedLock(targetElement) { targetElement.ontouchmove = (event) => { if (event.targetTouches.length === 1) { // detect single touch. - handleScroll(event, targetElement); + handleScroll(event, targetElement, isHorizontal); } }; } @@ -149,9 +149,12 @@ export default { } else { // lock everything but target element advancedLock(targetElement); - // lock everything but disabled targets + // lock everything but disabled targets with vertical scrolling const disabledTargets = document.querySelectorAll(`[${SCROLL_LOCK_DISABLE_ATTR}]`); disabledTargets.forEach(target => advancedLock(target)); + // lock everything but disabled targets with horizontal scrolling + const disabledHorizontalTargets = document.querySelectorAll(`[${SCROLL_LOCK_DISABLE_HORIZONTAL_ATTR}]`); + disabledHorizontalTargets.forEach(target => advancedLock(target, true)); } isLocked = true; }, @@ -167,7 +170,8 @@ export default { advancedUnlock(targetElement); // revert the old scroll position for disabled targets const disabledTargets = document.querySelectorAll(`[${SCROLL_LOCK_DISABLE_ATTR}]`); - disabledTargets.forEach(target => advancedUnlock(target)); + const disabledHorizontalTargets = document.querySelectorAll(`[${SCROLL_LOCK_DISABLE_HORIZONTAL_ATTR}]`); + [...disabledTargets, ...disabledHorizontalTargets].forEach(target => advancedUnlock(target)); } else { // remove all inline styles added by the `simpleLock` function document.body.style.removeProperty('overflow'); diff --git a/tests/unit/utils/scroll-lock.spec.js b/tests/unit/utils/scroll-lock.spec.js index 1a2ec8aca..5fbaad491 100644 --- a/tests/unit/utils/scroll-lock.spec.js +++ b/tests/unit/utils/scroll-lock.spec.js @@ -8,7 +8,7 @@ * See https://swift.org/CONTRIBUTORS.txt for Swift project authors */ -import scrollLock, { SCROLL_LOCK_DISABLE_ATTR } from 'docc-render/utils/scroll-lock'; +import scrollLock, { SCROLL_LOCK_DISABLE_ATTR, SCROLL_LOCK_DISABLE_HORIZONTAL_ATTR } from 'docc-render/utils/scroll-lock'; import { createEvent, parseHTMLString } from '../../../test-utils'; const { platform } = window.navigator; @@ -32,6 +32,7 @@ describe('scroll-lock', () => {
long
+
`); document.body.appendChild(DOM); @@ -90,23 +91,37 @@ describe('scroll-lock', () => { it('adds event listeners to the disabled targets too', () => { const disabledTarget = DOM.querySelector('.disabled-target'); + const disabledHorizontalTarget = DOM.querySelector('.disabled-horizontal-target'); // init the scroll lock scrollLock.lockScroll(container); // assert event listeners are attached expect(disabledTarget.ontouchstart).toEqual(expect.any(Function)); expect(disabledTarget.ontouchmove).toEqual(expect.any(Function)); + expect(disabledHorizontalTarget.ontouchstart).toEqual(expect.any(Function)); + expect(disabledHorizontalTarget.ontouchmove).toEqual(expect.any(Function)); scrollLock.unlockScroll(container); expect(disabledTarget.ontouchmove).toBeFalsy(); expect(disabledTarget.ontouchstart).toBeFalsy(); + expect(disabledHorizontalTarget.ontouchstart).toBeFalsy(); + expect(disabledHorizontalTarget.ontouchmove).toBeFalsy(); }); it('prevent event if user tries to perform vertical scroll in an horizontal scrolling element', () => { - Object.defineProperty(container, 'scrollWidth', { value: 100, writable: true }); + // set horizontal scrolling element only + DOM = parseHTMLString(` +
+
long
+
+
+ `); + document.body.appendChild(DOM); + container = DOM.querySelector('.container'); const touchStartEvent = { targetTouches: [{ clientY: 0, clientX: 0 }], }; + // perform vertical scroll const touchMoveEvent = { targetTouches: [{ clientY: -10, clientX: 0 }], preventDefault,