UNPKG

overscroll

Version:
174 lines (144 loc) 4.71 kB
export default ( scope ) => { const { target, overscroll, domData: { setData, hasData, removeData }, hasScrollY, hasScrollX, getNearestScrollable, getParent, NOBUBBLE } = scope; function handleState( states ) { return function( target, state = '' ) { if ( !hasData( target, state )) { states.filter(( elemState ) => { return state !== elemState && hasData( target, elemState ); }).forEach(( state ) => removeData( target, state )); if ( state && states.includes( state )) { setData( target, state ); } } }; } // 滚动位置 const setPositionX = handleState([ 'scrollLeft', 'scrollRight', 'scrollX' ]); const setPositionY = handleState([ 'scrollTop', 'scrollBottom', 'scrollY' ]); // 动画状态 const setAnimationX = handleState(['scrollingX']); const setAnimationY = handleState(['scrollingY']); // 方向 const setDirectionX = handleState([ 'scrollingLeft', 'scrollingRight' ]); const setDirectionY = handleState([ 'scrollingUp', 'scrollingDown' ]); function animatingX() { setAnimationX( target, 'scrollingX' ); } function animatingY() { setAnimationY( target, 'scrollingY' ); } function scrollingUp() { setDirectionY( target, 'scrollingUp' ); } function scrollingDown() { setDirectionY( target, 'scrollingDown' ); } function scrollingLeft() { setDirectionX( target, 'scrollingLeft' ); } function scrollingRight() { setDirectionX( target, 'scrollingRight' ); } function scrollingStopX() { setDirectionX( target ); setAnimationX( target ); } function scrollingStopY() { setDirectionY( target ); setAnimationY( target ); } function isTop( dom = overscroll ) { return dom.scrollTop < 1; } function isBottom( dom = overscroll ) { return dom.scrollTop === dom.scrollHeight - dom.clientHeight; } function isLeft( dom = overscroll ) { return dom.scrollLeft < 1; } function isRight( dom = overscroll ) { return dom.scrollLeft === dom.scrollWidth - dom.clientWidth; } function scrollableTo( dom ) { return { top: hasScrollY( dom ) && !isTop( dom ), left: hasScrollX( dom ) && !isLeft( dom ), right: hasScrollX( dom ) && !isRight( dom ), bottom: hasScrollY( dom ) && !isBottom( dom ) }; } function scrollable( dom, childrenState = { top: false, left: false, right: false, bottom: false }) { const scrollableDom = getNearestScrollable( dom ); const state = scrollableTo( scrollableDom ); if ( target === scrollableDom ) { return { top: state.top && !childrenState.top, left: state.left && !childrenState.left, right: state.right && !childrenState.right, bottom: state.bottom && !childrenState.bottom }; } return scrollable( getParent( scrollableDom ), { top: hasData( scrollableDom, NOBUBBLE ) || state.top || childrenState.top, left: hasData( scrollableDom, NOBUBBLE ) || state.left || childrenState.left, right: hasData( scrollableDom, NOBUBBLE ) || state.right || childrenState.right, bottom: hasData( scrollableDom, NOBUBBLE ) || state.bottom || childrenState.bottom }); } // 滚动状态设置完成后运行该函数 function resetState( scrollTop = 0, scrollLeft = 0 ) { // 位置判断 ----------------- // 纵向状态设置 if ( isTop()) { setPositionY( target, 'scrollTop' ); } else if ( isBottom()) { setPositionY( target, 'scrollBottom' ); } else { setPositionY( target, 'scrollY' ); } // 横向状态设置 if ( isLeft()) { setPositionX( target, 'scrollLeft' ); } else if ( isRight()) { setPositionX( target, 'scrollRight' ); } else { setPositionX( target, 'scrollX' ); } // 滚动状态判断 ---------------- if ( scrollTop === 0 || overscroll.scrollTop === scrollTop ) { scrollingStopY(); } else if ( overscroll.scrollTop > scrollTop ) { animatingY(); scrollingDown(); } else if ( overscroll.scrollTop < scrollTop ) { animatingY(); scrollingUp(); } if ( scrollLeft === 0 || overscroll.scrollLeft === scrollLeft ) { scrollingStopX(); } else if ( overscroll.scrollLeft > scrollLeft ) { animatingX(); scrollingRight(); } else if ( overscroll.scrollLeft < scrollLeft ) { animatingX(); scrollingLeft(); } } return { isTop, isBottom, isLeft, isRight, animatingX, animatingY, scrollingUp, scrollingDown, scrollingLeft, scrollingRight, scrollingStopX, scrollingStopY, resetState, scrollable }; };