移动端二三事【四】:移动端封装自定义滑动区域组件

在高性能要求的大型移动端项目中,使用移动端事件时必须的。而常规的固定定位在移动端的兼容性不是很友好。实际开发中的常见布局便是顶部标题栏固定于顶部,导航固定于底部,中间为可滑动的内容区域。因此封装移动端的滑动组件,就显得很有必要了。

而实际开发中,淘宝团队也是这种解决方案。

函数如下:

pomeloTween.js下载地址:https://github.com/pomelott/pomeloTween

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,user-scalable=no"/>
<title>自定义滑动</title>
<style type="text/css">
body {
    margin: 0;    
}
body,
html {
    height: 100%;
    overflow: hidden;
    position: relative;
}
header {
    height: 40px;
    font-size: 20px;
    color: #fff;
    text-align: center;
    background: #000;
    line-height: 40px;
}
footer {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 40px;
    color: #fff;
    text-align: center;
    background: #000;
    line-height: 40px;
}
#wrap {
    position: absolute;
    left: 0;
    right: 0;
    top: 40px;
    bottom: 40px;
    overflow: hidden;
}
#list {
    margin: 0;
    padding: 0;
    list-style: none;
}
#list li {
    line-height: 30px;
    text-indent: 20px;
    font-size: 16px;
    border-bottom: 1px solid #000;
}
</style>
<script type="text/javascript" src="pomeloTween.js"></script>
<script type="text/javascript">
function createList(){
    var list = document.querySelector('#list');
    var inner = "";
    for(var i = 0; i < 30; i++){
        inner += "<li>这是第"+i+"个li</li>"
    }    
    list.innerHTML = inner;
}
document.addEventListener('touchstart', function(e) {
    e.preventDefault();
});
window.onload = function(){
    createList();
    var wrap = document.querySelector('#wrap');
    mScroll({
        el:wrap,     //滚动区域结点
        offBar: true    //是否禁止滚动条
    })
};
function mScroll(init){
    if(!init.el){
        return;
    }
    var wrap = init.el;
    var inner = init.el.children[0];
    var scrollBar = document.createElement("div");    
    var startPoint = 0;
    var startEl = 0;
    var lastY = 0;
    var lastDis = 0;
    var lastTime = 0;
    var lastTimeDis = 0;
    var maxTranslate = wrap.clientHeight - inner.offsetHeight;
    if(!init.offBar){
        var scale = wrap.clientHeight/inner.offsetHeight;
        inner.style.minHeight = "100%";
        scrollBar.style.cssText = "6px;background:rgba(0,0,0,.5);position:absolute;right:0;top:0;border-radius:3px;opacity:0;transition:.3s opacity;";
        wrap.appendChild(scrollBar);
    }
    css(inner,"translateZ",0.01);
    inner.addEventListener('touchstart', function(e) {
        maxTranslate = wrap.clientHeight - inner.offsetHeight;
        if(!init.offBar){
            if(maxTranslate >= 0) {
                scrollBar.style.display = "none";
            } else {
                scrollBar.style.display = "block";
            }
            scale = wrap.clientHeight/inner.offsetHeight;
            scrollBar.style.height = wrap.clientHeight * scale + "px";
        }
        clearInterval(inner.timer);
        startPoint = e.changedTouches[0].pageY;
        startEl = css(inner,"translateY");
        lastY = startEl;
        lastTime = new Date().getTime();
        lastTimeDis = lastDis = 0;
        (init.offBar)||(scrollBar.style.opacity = 1);
    });
    inner.addEventListener('touchmove', function(e) {
        var nowTime = new Date().getTime();
        var nowPoint = e.changedTouches[0].pageY;
        var dis = nowPoint - startPoint;
        var translateY = startEl + dis;
        css(inner,"translateY",translateY);
        (init.offBar)||css(scrollBar,"translateY",-translateY*scale);
        lastDis = translateY - lastY;
        lastY = translateY;
        lastTimeDis = nowTime - lastTime;
        lastTime = nowTime;
    });
    inner.addEventListener('touchend', function(e) {
        var type = "easeOut";
        var speed = Math.round(lastDis / lastTimeDis*10);
        speed = lastTimeDis <= 0?0 :speed;
        var target = Math.round(speed*30 + css(inner,"translateY"));
        if(target > 0){
            target = 0;
            type = "backOut";
        } else if(target < maxTranslate){
            target = maxTranslate;
            type = "backOut";
        }
        MTween({
            el:inner,
            target: {translateY:target},
            time: Math.round(Math.abs(target - css(inner,"translateY"))*1.8),
            type: type,
            callBack: function(){
                (init.offBar) || (scrollBar.style.opacity = 0);
            },
            callIn: function(){
                var translateY = css(inner,"translateY");
                init.offBar||css(scrollBar,"translateY",-translateY*scale);
            }
        });
    });
}
</script>
</head>
<body>
<header id="header">自定义滑动</header>
<section id="wrap">
    <ul id="list">
        
    </ul>
</section>
<footer id="footer">底部导航</footer>    
</body>
</html>
原文地址:https://www.cnblogs.com/pomelott/p/7789266.html