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 overflowY = style . getPropertyValue ( 'overflow-y' ) ; const height = + parseFloat ( style . getPropertyValue ( 'height' ) ) . toFixed ( 0 ) ; const isScrollableY = 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' ) ) . toFixed ( 0 ) ; const isScrollableX = 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 ) ; } }