美文网首页
js楼层导航滚动

js楼层导航滚动

作者: 冒险小A | 来源:发表于2018-08-03 16:16 被阅读0次

需求:做一个仿电商或者b站右侧 那样的楼层导航
环境:原生js
学习知识点:

  • 练习scroll家族
  • 练习client家族
  • 练习缓动动画、定时器
  • 练习函数封装
  • 学习json遍历
  • 学习style[]传参
  • 练习简单闭包
  • 熟悉回调思想

封装的工具包myFunc.js

/**
 * 获取滚动的头部距离和左边距离
 * scroll().top scroll().left
 * @returns {*}
 */
function scroll() {
    if(window.pageYOffset !== null){
        return {
            top: window.pageYOffset,
            left: window.pageXOffset
        }
    }else if(document.compatMode === "CSS1Compat"){ // W3C
        return {
            top: document.documentElement.scrollTop,
            left: document.documentElement.scrollLeft
        }
    }

    return {
        top: document.body.scrollTop,
        left: document.body.scrollLeft
    }
}


function $(id) {
    return typeof id === "string" ? document.getElementById(id) : null;
}

/**
 * 获取屏幕的宽度和高度
 * @returns {*}
 */
function client() {
    if(window.innerWidth){ // ie9+ 最新的浏览器
        return {
            width: window.innerWidth,
            height: window.innerHeight
        }
    }else if(document.compatMode === "CSS1Compat"){ // W3C
        return {
            width: document.documentElement.clientWidth,
            height: document.documentElement.clientHeight
        }
    }

    return {
        width: document.body.clientWidth,
        height: document.body.clientHeight
    }
}


/**
 * 缓动动画
 * @param obj
 * @param json
 * @param fn
 */
function buffer(obj, json, fn) {
    // 1.1 清除定时器
    clearInterval(obj.timer);

    // 1.2 设置定时器
    var begin = 0, target = 0, speed = 0;
    obj.timer = setInterval(function () {
        // 1.3.0 旗帜
        var flag = true;
        for(var k in json){
            // 1.3 获取初始值
            if("opacity" === k){ // 透明度
                begin =  Math.round(parseFloat(getCSSAttrValue(obj, k)) * 100) || 100;
                target = parseInt(json[k] * 100);
            }else if("scrollTop" === k){
                begin = Math.ceil(obj.scrollTop);
                target = parseInt(json[k]);
            }else { // 其他情况
                begin = parseInt(getCSSAttrValue(obj, k)) || 0;
                target = parseInt(json[k]);
            }

            // 1.4 求出步长
            speed = (target - begin) * 0.2;

            // 1.5 判断是否向上取整
            speed = (target > begin) ? Math.ceil(speed) : Math.floor(speed);

            // 1.6 动起来
            if("opacity" === k){ // 透明度
                // w3c的浏览器
                obj.style.opacity = (begin + speed) / 100;
                // ie 浏览器
                obj.style.filter = 'alpha(opacity:' + (begin + speed) +')';
            }else if("scrollTop" === k){
                obj.scrollTop = begin + speed;
            }else {
                obj.style[k] = begin + speed + "px";
            }

            console.log(begin, target);

            // 1.5 判断
            if(begin !== target){
                flag = false;
            }
        }

        // 1.3 清除定时器
        if(flag){
            clearInterval(obj.timer);

            console.log(fn);

            // 判断有没有回调函数
            if(fn){
                fn();
            }
        }
    }, 20);
}

主体实现index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        *{
            margin: 0;
            padding: 0;
            list-style: none;
            border:0;
        }

        html, body, ul{
            width: 100%;
            height: 100%;
        }

        #ul li{
            width: 100%;
            height: 100%;
            text-align: center;
            font-size: 30px;
            /*background-color: red;*/
            color: #fff;
        }

        #ol{
            width: 80px;
            background-color: #ccc;
            position: fixed;
            left: 50px;
            top: 200px;
            border: 1px solid #fff;
        }

        #ol li{
            text-align: center;
            line-height: 30px;
            border-bottom: 1px solid #fff;
            color: #fff;
            cursor: pointer;
        }

        #ol li.current{
            background-color: orangered;
        }
    </style>
</head>
<body>
    <!--GPS-->
    <ol id="ol">
        <li class="current">第1层</li>
        <li>第2层</li>
        <li>第3层</li>
        <li>第4层</li>
        <li>第5层</li>
    </ol>
    <!--楼层-->
    <ul id="ul">
        <li>第1层内容</li>
        <li>第2层内容</li>
        <li>第3层内容</li>
        <li>第4层内容</li>
        <li>第5层内容</li>
    </ul>
<script src="js/myFunc.js"></script>
<script>
    window.onload = function () {
        // 1. 获取需要的标签
        var ol = $('ol'), ul = $('ul');
        var ulLis = ul.children;
        var olLis = ol.children;
        //设置变量分离"自由滚动"和"点击导航滚动",使相互不影响
        var isClick = false;


        // 2. 上色
        var colorArr = ['red', 'green', 'blue', 'purple', 'yellow'];
        for(var i=0; i<colorArr.length; i++){
            ulLis[i].style.backgroundColor = colorArr[i];
        }
        
        // 3. 监听GPS的点击
        for(var j=0; j<olLis.length; j++){
            (function (index) {
                 var olLi = olLis[index];
                 // 3.1 点击切换
                olLi.onmousedown = function () {

                    isClick = true;

                    for(var i = 0; i<olLis.length; i++){
                        olLis[i].className = "";
                    }
                    this.className = "current";

                    // 3.2 让内容滚动起来
                    // document.documentElement.scrollTop = index * client().height;
                    buffer(document.documentElement, {scrollTop: index * client().height}, function () {
                      isClick = false;
                    });
                }
            })(j);
        }
        
        // 4.监听滚动
        window.onscroll = function () {
           if(!isClick){
               // 4.1 获取滚动产生的高度
               var roll = Math.ceil(scroll().top);
               // 4.2 遍历
               for(var i=0; i<olLis.length; i++){
                   // 4.3 判断
                   if(roll >= ulLis[i].offsetTop){
                       for(var j=0; j<olLis.length; j++){
                           olLis[j].className = "";
                       }
                       olLis[i].className = "current";
                   }
               }
           }
        }
    }
</script>
</body>

总结:
发现兼容性很差,ie不兼容

相关文章

网友评论

      本文标题:js楼层导航滚动

      本文链接:https://www.haomeiwen.com/subject/mxtuvftx.html