筋斗云案例

首先把html和css的基础样式写好

<style>
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            height: 30px;
            margin: 0 auto;
            position: relative;
            margin: 100px auto;
            width: 500px;
        }
        .box .contaner li{
            width: 100px;
            line-height: 30px;
            text-align: center;
            background-color: pink;
            float: left;
            list-style: none;
        }
        .box .yun {
            width: 100px;
            height: 30px;
            background-color: blue;
            position: absolute;
        }
       
    </style>
    <div class="box">
        <div class="yun"></div>
        <ul class="contaner">
            <li>0</li>
            <li>1</li>
            <li>2</li>
            <li>3</li>
            <li>4</li>
        </ul>
    </div>

分析功能需求

  1. 滑块随着鼠标动画的移动效果

    滑块的移动效果最好用css来做,js主要是负责逻辑

  2. 鼠标离开,滑块又回到起始位置

  3. 点击鼠标,改变起始位置

		/*
        功能需求:
            1.yun移动后
            2.yun返回
            3.点击后改变起始位置
        */
        var start = 0;	// 控制其改变起始位置
        var box = document.querySelector('.box')
        var yun = document.querySelector('.yun');
        var contaner = document.querySelector('.contaner');
        var contaner_list = contaner.querySelectorAll('li');
       
        // 给每个li添加事件,采用闭包的思想
        for(var i =0;i < contaner_list.length; i++) {
            (function(i) {
                contaner_list[i].addEventListener('mouseover',function() {
                    yun.style.transition = 'all .2s linear 0s';
                    yun.style.left = i*100 + 'px';
                    console.log(i)
                })
                yun.onclick = function() {
                    start = this.offsetLeft;
                    console.log(start);
                }
            })(i)
        }
        box.addEventListener('mouseleave',function() {
            yun.style.transition = 'all .2s linear 0s';
            console.log(yun.className);
            yun.style.left = start + 'px';
        })

出现的问题

最开始的时候用的是函数function来写动画效果,但出现了滑块抖动的问题

        // 动画效果函数
        function animate(obj,target,callback) {
            clearInterval(obj.timer);
            var step;
            obj.timer = setInterval(() => {
                step = (target - obj.offsetLeft)/5;
                step = step > 0 ? Math.ceil(step):Math.floor(step);
                obj.style.left = obj.offsetLeft + step + 'px';
                if(obj.offsetLeft == target) {
                    clearInterval(obj.timer);
                    callback ?  callback(): callback;
                }
            }, 100);
        }
// 每个事件
var flag = true // 最开始设置为true
        for(var i =0;i < contaner_list.length; i++) {
            contaner_list[i].addEventListener('mouseover',function() {
                if(flag) {
                    flag = false;
                    animate(yun,this.offsetLeft,function() {
                        flag = true;
                    });
                }
            })
            contaner_list[i].addEventListener('mouseleave',function() {
                if(flag) {
                    flag = false;
                    animate(yun,start,function() {
                        flag = true;
                    });
                    console.log(start);
                }
            })
            contaner_list[i].addEventListener('click',function() {
                start = this.offsetLeft;
            })

出现抖动的原因在于:执行离开事件,if中的flag就不会成立,逻辑在移动比较慢的时候不会出现bug,一旦移动快了,就会有问题

posted @ 2022-05-19 21:10  a立方  阅读(75)  评论(0编辑  收藏  举报