Mobile

宋乐
宋乐 2017年11月21日

note some js code in mobile

scroll smooth

code

// scrollSmooth.js
module.exports = function (elem) {
    var startY, endY, startTime, endTime;
    var speedDecay = 0.02; //速度衰减量  
    var lastMoveTime, secondLastMoveTime; //最后次手指停止移动的时间和倒数第二次手指停止移动的时间(测试的时发现有时候最后一次移动时间不准确,故而选用倒数第二次停止移动的时间)  
    var stopMoveInterval; //手指停止滑动的时间  

    var stopInertiaMove = false; //停止惯性滚动的标识位  


    var oldPageY = null;
    var oldScrollTop = null;
    elem.addEventListener('touchstart', function (e) {
        oldScrollTop = elem.scrollTop
        stopInertiaMove = true; //当惯性滑动过程中再次触碰到屏幕的时候应该立即停止惯性滑动  
        startY = e.touches[0].pageY;
        startTime = Date.now();
    });



    elem.addEventListener('touchmove', function (e) {
        //这个事件主要用来记录最后一次停止滑动的时间,当停止滑动时间超过一定量就不执行惯性滑动  
        secondLastMoveTime = lastMoveTime;
        if (oldPageY) { //正常速度滚动
            let top = oldScrollTop + (oldPageY - e.touches[0].pageY)
            elem.scrollTop = top
        }
        if (!oldPageY) oldPageY = e.touches[0].pageY

        lastMoveTime = Date.now();
    });

    elem.addEventListener('touchend', function (e) {
        oldPageY = null
        endY = e.changedTouches[0].pageY;
        endTime = Date.now();
        if (secondLastMoveTime) {
            stopMoveInterval = endTime - secondLastMoveTime;
        } else {
            stopMoveInterval = endTime - lastMoveTime;
        }

        //计算速度,距离除以时间  
        var speed = (endY - startY) / (endTime - startTime);
        var speedAbs = Math.abs(speed);

        /** 
         * 惯性移动的递归方法 
         */
        function inertiaMove() {
            if (speedAbs < 0 || stopInertiaMove) {
                //如果速度绝对值小于0了,则结束惯性滚动  
                return;
            }


            //设置每次惯性滑动时间为20毫秒  
            var distance = speedAbs * 20;


            if (speed < 0) {
                //如果速度是负数,则是手指向上滑动。继续惯性滚动,则scrollTop的值会增加  
                elem.scrollTop += distance;
                //console.log('向上惯性滚动' + distance);  
            } else {
                //如果速度是正数,则是手指向下滑动。继续惯性滚动,则scrollTop的值会减少  
                elem.scrollTop -= distance;
                //console.log('向下惯性滚动' + distance);  
            }


            //速度衰减  
            speedAbs -= speedDecay;

            setTimeout(inertiaMove, 10);
        }

        if (stopMoveInterval < 100) {
            //手指停止滑动超过0.1秒的就不执行惯性滑动了  
            stopInertiaMove = false;
            inertiaMove();
        }
    });
}

usage

import MyScroll from './util/scrollSmooth'
let ele = document.getElelmetById('xxx')
MyScroll(ele)

ban wechat and browser body default scroll pull

code

document.addEventListener('touchmove', function (e) {
    e.preventDefault();
});