Skip to content

Instantly share code, notes, and snippets.

@yinxin630
Last active August 16, 2019 09:00
Show Gist options
  • Save yinxin630/71622778ff7822b030afde41df44f153 to your computer and use it in GitHub Desktop.
Save yinxin630/71622778ff7822b030afde41df44f153 to your computer and use it in GitHub Desktop.
ios橡皮筋效果问题|-|&tag=code
/**
* 阻止目标元素下不必要的滚动事件. 解决ios橡皮筋效果问题
* 需要滚动的元素需要添加 overflow-x/y: auto (务必为单方向) 和 -webkit-overflow-scrolling: touch 样式
* @param {HTMLElement} targetElement 目标元素
*/
export default function inobounce(targetElement) {
let startX = 0;
let startY = 0;
function handleTouchStart(e) {
startY = e.touches ? e.touches[0].screenY : e.screenY;
startX = e.touches ? e.touches[0].screenX : e.screenX;
}
function handleTouchMove(e) {
let el = e.target;
while (el !== e.currentTarget) {
const style = window.getComputedStyle(el);
if (!style) {
break;
}
if (el.nodeName === 'INPUT' && el.getAttribute('type') === 'range') {
return;
}
const scrolling = 'touch';
const overflowY = style.getPropertyValue('overflow-y');
const height = parseFloat(style.getPropertyValue('height'), 10).toFixed(0);
const isScrollableY = scrolling === 'touch' && (overflowY === 'auto' || overflowY === 'scroll');
const canScrollY = el.scrollHeight > el.offsetHeight;
if (isScrollableY && canScrollY) {
const curY = e.touches ? e.touches[0].screenY : e.screenY;
const isAtTop = (startY <= curY && el.scrollTop === 0);
const isAtBottom = (startY >= curY && el.scrollHeight - el.scrollTop == height);
if (isAtTop || isAtBottom) {
e.preventDefault();
}
return;
}
const overflowX = style.getPropertyValue('overflow-x');
const width = parseFloat(style.getPropertyValue('width'), 10).toFixed(0);
const isScrollableX = scrolling === 'touch' && (overflowX === 'auto' || overflowX === 'scroll');
const canScrollX = el.scrollWidth > el.offsetWidth;
if (isScrollableX && canScrollX) {
const curX = e.touches ? e.touches[0].screenX : e.screenX;
const isAtLeft = (startX <= curX && el.scrollLeft === 0);
const isAtRight = (startX >= curX && el.scrollWidth - el.scrollLeft == width);
if (isAtLeft || isAtRight) {
e.preventDefault();
}
return;
}
el = el.parentNode;
}
e.preventDefault();
}
if (targetElement) {
targetElement.addEventListener('touchstart', handleTouchStart);
targetElement.addEventListener('touchmove', handleTouchMove);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment