I created a website with jQueryMobile for iOS and Android.
I don\'t want the document itself to scroll. Instead, just an area (a element) sh
Here is my implementation which works on touch devices and laptops.
function ScrollManager() {
let startYCoord;
function getScrollDiff(event) {
let delta = 0;
switch (event.type) {
case 'mousewheel':
delta = event.wheelDelta ? event.wheelDelta : -1 * event.deltaY;
break;
case 'touchstart':
startYCoord = event.touches[0].clientY;
break;
case 'touchmove': {
const yCoord = event.touches[0].clientY;
delta = yCoord - startYCoord;
startYCoord = yCoord;
break;
}
}
return delta;
}
function getScrollDirection(event) {
return getScrollDiff(event) >= 0 ? 'UP' : 'DOWN';
}
function blockScrollOutside(targetElement, event) {
const { target } = event;
const isScrollAllowed = targetElement.contains(target);
const isTouchStart = event.type === 'touchstart';
let doScrollBlock = !isTouchStart;
if (isScrollAllowed) {
const isScrollingUp = getScrollDirection(event) === 'UP';
const elementHeight = targetElement.scrollHeight - targetElement.offsetHeight;
doScrollBlock =
doScrollBlock &&
((isScrollingUp && targetElement.scrollTop <= 0) ||
(!isScrollingUp && targetElement.scrollTop >= elementHeight));
}
if (doScrollBlock) {
event.preventDefault();
}
}
return {
blockScrollOutside,
getScrollDirection,
};
}
const scrollManager = ScrollManager();
const testBlock = document.body.querySelector('.test');
function handleScroll(event) {
scrollManager.blockScrollOutside(testBlock, event);
}
window.addEventListener('scroll', handleScroll);
window.addEventListener('mousewheel', handleScroll);
window.addEventListener('touchstart', handleScroll);
window.addEventListener('touchmove', handleScroll);
.main {
border: 1px solid red;
height: 200vh;
}
.test {
border: 1px solid green;
height: 300px;
width: 300px;
overflow-y: auto;
position: absolute;
top: 100px;
left: 50%;
}
.content {
height: 100vh;
}