封装一个自定义hooks
import { useRef, useState, useEffect } from 'react';
export useFixRollingPenetration = (domId) => {
let targetLeftY = 0;
const isMiniAppType = isMiniApp || isRealWeChatMiniProgram;
const disableTouchMove = useRef((e) => {
const scrollBox = document.getElementById(domId)
if (scrollBox) {
//target是否在scrollBox之内,不在范围内就别滚动
if (!scrollBox.contains(e.target)) {
e.preventDefault();
}
}
});
const preventScrolling = () => {
if (!isMiniAppType && document && document.body) {
document.body.addEventListener('touchmove', disableTouchMove.current, {
passive: false,
});
}
};
const allowScrolling = () => {
if (!isMiniAppType && document && document.body) {
document.body.removeEventListener('touchmove', disableTouchMove.current, {
/** @ts-ignore */
passive: false,
});
}
};
function onTouchStart(e) {
targetLeftY = Math.floor(e.targetTouches[0].clientY);
}
function onTouchMove(e) {
let newTargetY = Math.floor(e.targetTouches[0].clientY);
let dom = document.getElementById(domId);
let sT = dom.scrollTop;
let sH = dom.scrollHeight;
let cH = dom.clientHeight;
// 判断是否滚动溢出,溢出后e.preventDefault();
if (sT <= 0 && newTargetY - targetLeftY > 0 && targetLeftY !== 0) {
e.preventDefault();
} else if ((sT >= sH - cH) && (newTargetY - targetLeftY < 0)) {
e.preventDefault();
}
}
return {
preventScrolling,
allowScrolling,
onTouchStart,
onTouchMove,
}
}
输入未传入的dom id字符串,输出为四个方法
使用:
const {
preventScrolling,
allowScrolling,
onTouchStart,
onTouchMove,
onTouchEnd
} = useFixRollingPenetration('brand-scroll');
useEffect(() => {
if (showPad) {
preventScrolling();
} else {
allowScrolling();
}
return () => {
allowScrolling();
}
}, [showPad])
<div className="brand-scroll-wrapper" id='brand-scroll'
onTouchStart={onTouchStart}
onTouchMove={onTouchMove}
/>