美文网首页
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