javaScript动画项目案例

示例代码:我的github
demo效果演示示例:我的demo网站

1.动画库编写

匀速运动

案例一

效果:匀速运动

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box {
            width: 100px;
            height: 100px;
            background-color: red;
            position: absolute;
        }
    </style>
</head>

<body>
    <h2>
        匀速运动
    </h2>
    <button id="btn">按钮</button>
    <div id="box">

    </div>

    <script>
        var box = document.getElementById('box');
        var btn = document.getElementById('btn');
        console.log(box.style.left);
        // 设置定时器  边界问题 定时器处理
        let timer = null;
        let max_val = 500;
        let count = 0;
        btn.onclick = function () {
            // 1.清除定时器
            clearInterval(timer);
            // 2.设置定时器
            timer = window.setInterval(function () {
                // 3.判断边界
                if (count >= max_val) {
                    clearInterval(timer);
                    return;
                }
                count += 1;
                box.style.left = count + 'px';
            }, 30)
        }
    </script>
</body>

</html>

使用定时器控制位置

案例二:侧边栏效果

效果:侧边栏效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 300px;
            height: 100px;
            position: relative;
            background-color: blue;
            left: -300px;
        }

        #box span {
            width: 50px;
            height: 100px;
            left: 300px;
            position: absolute;
            background-color: #000000;
            color: #ffffff;
            text-align: center;
            line-height: 100px;
        }
    </style>
</head>

<body>
    <div id="box">
        <span>拉开</span>
    </div>
    <script>
        const pull = document.querySelector('#box span');
        const box = document.querySelector('#box');
        box.onmouseover = function () {
            startAnimation(this,0);
        }
        box.onmouseout = function () {
            startAnimation(this,-300);
        }
        let timer = null;
        let speed = 0;
        // obj代表动画对象  end 代表结束坐标
        function startAnimation(obj, end) {
            // 1.清除定时器
            clearInterval(timer);
            timer = setInterval(function () {
                // 计算速度
                speed = obj.offsetLeft > end ? -5 : 5;
                // 2.结束条件
                if (obj.offsetLeft == end) {
                    clearInterval(timer);
                    return;
                }
                // 3.执行动画
                obj.style.left = obj.offsetLeft + speed + 'px';
            }, 50)
        }
    </script>
</body>
</html>

缓动运动

效果:缓动运动
缓动运动就是通过控制速度,使动画达到淡出效果

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #box {
            width: 300px;
            height: 100px;
            position: relative;
            background-color: blue;
            left: -300px;
        }

        #box span {
            width: 50px;
            height: 100px;
            left: 300px;
            position: absolute;
            background-color: #000000;
            color: #ffffff;
            text-align: center;
            line-height: 100px;
        }
    </style>
</head>

<body>
    <div id="box">
        <span>拉开</span>
    </div>
    <script>
        const pull = document.querySelector('#box span');
        const box = document.querySelector('#box');
        box.onmouseover = function () {
            startAnimation(this,0);
        }
        box.onmouseout = function () {
            startAnimation(this,-300);
        }
        let timer = null;
        let speed = 0;
        // obj代表动画对象  end 代表结束坐标
        function startAnimation(obj, end) {
            // 1.清除定时器
            clearInterval(timer);
            timer = setInterval(function () {
                // 计算速度
                speed = (end - box.offsetLeft)/20;
                // 计算速度  速度为负数时,用floor保证最小为-1  速度为正数时,用ceil保证最小为1
                speed = obj.offsetLeft > end ? Math.floor(speed) : Math.ceil(speed);
                // 2.结束条件
                if (obj.offsetLeft == end) {
                    clearInterval(timer);
                    return;
                }
                // 3.执行动画
                obj.style.left = obj.offsetLeft + speed + 'px';
            }, 50)
        }
    </script>
</body>

</html>

注意:
speed = (end - box.offsetLeft)/20;
代表用(终点位置-当前位置)/动画系数
动画系数可以控制动画的快慢

透明度运动

效果:透明度运动
通过修改透明度变化进而修改动画

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box{
            width: 100px;
            height: 100px;
            background-color: red;
            opacity: 0.3;
            filter: alpha(opacity:30);
        }
    </style>
</head>
<body>
    <div id="box">

    </div>
    <script>
        const box = document.getElementById('box');
        box.onmouseover = function () {
            opacityAnimation(this,100);
        }
        box.onmouseout = function () {
            opacityAnimation(this,30);
        }
        let timer = null,speed = 0,alpha = 30; // alpha:透明度数值
        function opacityAnimation(obj,end) {
            // 1.清除原定时器
            clearInterval(timer);
            // 2.设置新定时器
            timer = setInterval(function () {
                // 3.设置速度数值
                speed = (end - alpha) / 20;
                speed = end > alpha ? Math.ceil(speed):Math.floor(speed);
                // 3.边界处理
                if(alpha === end){
                    clearInterval(timer);
                    return ;
                }
                // 4.运动 设置属性
                alpha += speed
                obj.style.opacity = alpha / 100;  //用于一般浏览器  
                obj.style.filter = `alpha(opacity:${alpha})`; //用于ie8及以下浏览器
            },30)

        }
    </script>
</body>
</html>

多物体运动

效果:多物体运动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box1{
            width: 100px;
            height: 100px;
            background-color: red;
            position: relative;
        }
        #box2{
            width: 100px;
            height: 100px;
            background-color: blue;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <div id="box2"></div>
    <script>
        const box1 = document.getElementById('box1');
        const box2 = document.getElementById('box2');
        box1.onmouseover = function () {
            startAnimation(box1,500);
        }
        box1.onmouseout = function () {
            startAnimation(box1,100);
        }
        box2.onmouseover = function () {
            startAnimation(box2,500);
        }
        box2.onmouseout = function () {
            startAnimation(box2,100);
        }
        let speed=0;
        // 多物体运动时,timer绑在对象上面
        function startAnimation(obj,end) {
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                if(end === obj.offsetWidth){  // offsetWidth: 盒子的width+border
                    clearInterval(obj.timer);
                    return;
                }
                // 运动
                speed = end > obj.offsetWidth ? 10:-10;
                obj.style.width = obj.offsetWidth + speed + 'px';
            },30)
        }
    </script>
</body>
</html>

注意:多物体运动时,定时器需要绑在对象上,清除定时器时,只需要清除自己的定时器即可

多值运动

效果:多值运动
将上述代码进一步封装,使其可以针对任意属性变化都能产生动画效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box1{
            width: 100px;
            height: 100px;
            background-color: red;
            position: relative;
        }
        #box2{
            width: 100px;
            height: 100px;
            background-color: blue;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <div id="box2"></div>
    <script>
        const box1 = document.getElementById('box1');
        const box2 = document.getElementById('box2');
        box1.onmouseover = function () {
            startAnimation(box1,"width",500);
        }
        box1.onmouseout = function () {
            startAnimation(box1,"width",100);
        }
        box2.onmouseover = function () {
            startAnimation(box2,"opacity",30);
        }
        box2.onmouseout = function () {
            startAnimation(box2,"opacity",100);
        }
        let speed=0;

        function startAnimation(obj,attr,end) {
            clearInterval(obj.timer);
            obj.timer = setInterval(function () {
                let cur = 0;
                if(attr === 'opacity'){
                    cur = Math.round(parseFloat(getStyle(obj,attr)) * 100);  // 透明度默认为0到1之间,将透明度获取的值*100  
                }else{
                    cur = parseInt(getStyle(obj,attr));
                }
                if(end === cur){
                    clearInterval(obj.timer);
                    return;
                }
                // 运动
                speed = end > cur ? 10:-10;
                if(attr === 'opacity'){
                    // 设置透明度
                    obj.style[attr] = (cur + speed) / 100;
                    obj.style['filter'] = `alpha(opacity:${cur + speed})`;
                }else{
                    obj.style[attr] = cur + speed + 'px';
                }
                
            },30)
        }
        // 获取属性  因为使用obj.style获取的属性仅仅为内嵌的值,获取不到行内样式和外部引用的值
        function getStyle(obj,attr) { 
            if(obj.currentStyle){
                // 针对IE浏览器
                return obj.currentStyle[attr];
            }else{
                // 针对于Firefox浏览器
                return getComputedStyle(obj,null)[attr];
            }
        }
    </script>
</body>
</html>

链式运动

效果:链式运动
可以让物体先变宽再变长,只需要将上述代码加回调函数的参数即可
myAnimation.js

/**
 * 动画函数
 * @param {Object} obj 当前对象
 * @param {Object} attr 当前元素对象的属性
 * @param {Object} end 末尾位置
 * @param {Object} fn 回调函数
 * */
function startAnimation(obj,attr,end,fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        let cur = 0,speed = 0;
        if(attr === 'opacity'){
            cur = Math.round(parseFloat(getStyle(obj,attr)) * 100); 
            // console.log(getStyle(obj,attr));
        }else{
            cur = parseInt(getStyle(obj,attr));
        }
        if(end === cur){
            clearInterval(obj.timer);
            // 回调函数放在动画执行结束之后
            if(fn){
                fn();
            }
            return;
        }
        // 运动
        speed = end > cur ? 10:-10;
        if(attr === 'opacity'){
            // console.log(cur + speed);
            obj.style[attr] = (cur + speed) / 100;
            obj.style['filter'] = `alpha(opacity:${cur + speed})`;
        }else{
            obj.style[attr] = cur + speed + 'px';
        }
        
    },30)
}
// 获取属性
function getStyle(obj,attr) { 
    if(obj.currentStyle){
        // 针对IE浏览器
        return obj.currentStyle[attr];
    }else{
        // 针对于Firefox浏览器
        return getComputedStyle(obj,null)[attr];
    }
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box1{
            width: 100px;
            height: 100px;
            background-color: red;
            position: relative;
        }
        #box2{
            width: 100px;
            height: 100px;
            background-color: blue;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <div id="box2"></div>
    <script src="myAnimation.js"></script>
    <script>
        const box1 = document.getElementById('box1');
        const box2 = document.getElementById('box2');
        // 链式运动
        box1.onmouseover = function () {
            startAnimation(box1,"width",500,function () {
                startAnimation(box1,"height",500,function () {
            });
            });
        }
        box1.onmouseout = function () {
            startAnimation(box1,"width",100);
        }
        box2.onmouseover = function () {
            startAnimation(box2,"opacity",30);
        }
        box2.onmouseout = function () {
            startAnimation(box2,"opacity",100);
        }
        // 多物体运动时,timer绑在对象上面

    </script>
</body>
</html>

同时运动

效果:同时运动
可以让物体同时变长变宽,修改原来代码,将传入的属性和值改成传入json格式类型

动画库最终版本
myAnimation2.js

/**
 * 动画函数
 * @param {Object} obj 当前对象
 * @param {Object} json 当前元素属性列表
 * @param {Object} fn 回调函数
 * */
function startAnimation(obj,json,fn) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        let cur = 0,speed = 0;  
        let flag = true; // flag:代表所有动画执行完毕

        // 将json中所有元素属性遍历,修改
        for(attr in json){
            let end = json[attr];

            // 获取对象属性值
            switch(attr){
                case "opacity":
                    cur = Math.round(parseFloat(getStyle(obj,attr)) * 100);
                    break;
                case "scrollTop":
                    cur = obj[attr];
                    break;
                default:
                    cur = parseInt(getStyle(obj,attr));
            }

            // 临界处理 该动画没有执行完毕
            if(end !== cur){
                flag = false;
            }else{
                continue;
            }
            console.log(cur);
            // 设置速度:判断结束值end和当前值cur相差值小于speed速度
            if(end > cur){ 
                // end=100 cur=92   speed=10
                speed = end - cur < 100?end - cur:100;
            }else{
                // end=0 cur=2 speed=-10
                speed = end - cur > -100?end - cur:-100;
            }

            // 设置值
            switch(attr){
                case "opacity":
                    obj.style[attr] = (cur + speed) / 100;
                    obj.style['filter'] = `alpha(opacity:${cur + speed})`;
                    break;
                case "scrollTop":
                    obj[attr] = cur + speed;
                    break;
                default:
                    obj.style[attr] = cur + speed + 'px';
            }
        }
        // 查看flag是否为true,  都当所有属性都没有被修改时,flag为true,结束动画
        if(flag){
            clearInterval(obj.timer);
            if(fn){
                fn();
            }
            return ;
        }
    },30)
}
// 获取属性
function getStyle(obj,attr) { 
    if(obj.currentStyle){
        // 针对IE浏览器
        return obj.currentStyle[attr];
    }else{
        // 针对于Firefox浏览器
        return getComputedStyle(obj,null)[attr];
    }
}

使用for遍历json,将每个属性修改,直到最后,当每个属性都到最终值时,条件结束,清除定时器
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #box1{
            width: 100px;
            height: 100px;
            background-color: red;
            position: relative;
        }
        #box2{
            width: 100px;
            height: 100px;
            background-color: blue;
            position: relative;
        }
    </style>
</head>
<body>
    <div id="box1"></div>
    <div id="box2"></div>
    <script src="myAnimation2.js"></script>
    <script>
        const box1 = document.getElementById('box1');
        const box2 = document.getElementById('box2');
        // 链式运动
        box1.onmouseover = function () {
            startAnimation(box1,{
                "width":500,
                "height":800
            });
        }
        box1.onmouseout = function () {
            startAnimation(box1,{
                "width":100,
                "height":100
            });
        }
        box2.onmouseover = function () {
            startAnimation(box2,{
                "opacity":30,
                "width":600
            });
        }
        box2.onmouseout = function () {
            startAnimation(box2,{
                "opacity":100,
                "width":100
            });
        }
    </script>
</body>
</html>

案例

案例一:关闭页脚广告效果

效果:关闭页脚广告效果
点击关闭按钮,右下角广告就会先向下移动再向右移动至消失,具体myAnimation2.js文件在上述有写到
点击前往myAnimation2.js文件内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            padding: 0;
            margin: 0;
        }
        #ad{
            position: fixed;
            bottom: 0;
            right: 0;
        }
        #close{
            width: 25px;
            height: 25px;
            position: absolute;
            top: 0;
            right: 0;
            z-index: 5;
        }

    </style>
</head>
<body>
    <div id="ad">
        <img src="./ad.png" alt="" width="300px">
        <span id="close"></span>
    </div>
    <script src="./myAnimation2.js"></script>
    <script>
        const ad = document.getElementById('ad');
        const close = document.getElementById('close');
        close.onclick = function () {
            startAnimation(ad,{"height":260},function () {
                startAnimation(ad,{"width":0},function () {
                    ad.style.display = 'none';
                  })
              });
        }
    </script>
</body>
</html>

案例二:侧边栏横幅效果

效果:侧边栏横幅效果
左侧中间的广告随着页面移动,而一直向中间移动的动画
点击前往myAnimation2.js文件内容

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #aside{
            position: absolute;
            top: 200px;
            left: 0;
            width: 300px;
        }
        img{
            width: 100%;
        }
    </style>
</head>
<body style="height:5000px">
    <div id="aside">
        <img src="./aside.png" alt="">
    </div>
    <script src="./myAnimation2.js"></script>
    <script>
        window.onload = function () {
            const aside = document.getElementById('aside');
            const aside_top = aside.offsetTop;  // 距离浏览器顶部的位置
            window.onscroll = function () {
                // 页面滚动的距离
                let docScroll = document.documentElement.scrollTop || document.body.scrollTop;
                // 设置动画
                startAnimation(aside,{
                    'top':aside_top+docScroll
                })
            }
        }
    </script>
</body>
</html>

offsetTop 偏移量,相当于绝对定位的子盒子的top属性
docScroll 使用兼容性写法,因为获取滚动高度可能由于浏览器不同获取方法不同

案例三:淘宝侧边导航效果

效果:淘宝侧边导航效果
右侧侧边导航,随着页面移动,导航条上也移动到相应栏目;如果点击导航条上板块名,页面也会移动到相应板块处
点击前往myAnimation2.js文件内容

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            list-style: none;
        }
        a{
            text-decoration: none;
        }

        html,body{
            width: 100%;
            height: 100%;
        }
        #container{
            width: 1200px;
            margin: 0 auto;
            height: 100%;
        }
        #container div{
            width: 100%;
            height: 100%;
            text-align: center;
            color: #fff;
            font-size: 30px;
        }

        .aside{
            position: fixed;
            width: 40px;
            right: 20px;
            top: 300px;
            font-size: 16px;
            font-weight: 700;
            text-align: center;
        }
        .aside li{
            height: 50px;
            border-bottom: 1px solid #ddd;
            
        }
        .aside li a{
            color: peru;
        }
        .aside li.current{
            background-color: peru;
        }
        .aside li.current a{
            color: #fff;
        }
    </style>
</head>
<body>
    <div id="container">
        <div class="current">爱逛好货</div>
        <div>好店直播</div>
        <div>品质特色</div>
        <div>实惠热卖</div>
    </div>
    <ul class="aside" id="aside">
        <li class="current"><a href="javascript:void(0);">爱逛好货</a></li>
        <li><a href="javascript:void(0);">好店直播</a></li>
        <li><a href="javascript:void(0);">品质特色</a></li>
        <li><a href="javascript:void(0);">实惠热卖</a></li>
    </ul>
    <script src="./myAnimation2.js"></script>
    <script>
        // 获取对象
        const aside = document.getElementById('aside');
        const lis = aside.children;
        const Odiv = document.getElementById("container");
        const Divs = Odiv.children;

        // 给盒子上色
        colors = ['blue','purple','orange','green'];
        [...Divs].forEach((element,i,arr)=>{
            element.style.backgroundColor = colors[i];
        });

        // 设置侧边栏点击事件
        let isClick = false;  // 点击触发滚动的标准
        [...lis].forEach((element,i,arr) => {
            element.onclick = function (){
                arr.forEach(el=>{
                el.className = "";
                })
                this.className = "current";
                // document.documentElement.scrollTop = i * document.documentElement.clientHeight;
                // 制作点击侧边栏,内容部分滚动相应位置的动画
                isClick = true;
                startAnimation(document.documentElement,{
                    "scrollTop":i * document.documentElement.clientHeight
                },function () {
                    isClick = false;
                  })
            }
        });

        // 监听滚动  滚动到相应位置,侧边栏也会调整active
        window.onscroll = function () {
            // 如果用户不是因为点击侧边栏而触发的滚动
            if(!isClick){
                // 获取当前滚动值
                let top = document.documentElement.scrollTop || document.body.scrollTop;
                let i = Math.floor(top / document.documentElement.clientHeight);  // 计算索引
                // 排他
                [...lis].forEach(element=>element.className = "");
                lis[i].className = "current";
            }
        }
    </script>
</body>
</html>

[…Divs] 使用了es6写法,将dom获取的集合类型转换为真正的数组,有forEach变量方法;这一步等价于使用for(element in Divs) 循环

案例四:轮播图

效果:轮播图
可以自动滚动,鼠标悬停时,取消滚动;可以上一页下一页,可以点击索引跳到相应位置
点击前往myAnimation2.js文件内容
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/index.css">
</head>
<body>
    <div id="slider" class="slider">
        <div class="slider_scroll" id="slider_scroll">
            <!-- 轮播图部分 -->
            <div class="slider_main" id="slider_main">
                <!-- 每一个轮播图元素 -->
                <div class="item">
                    <a href="#">
                        <img src="./images/img1.png" alt="">
                    </a>
                </div>
                <div class="item">
                    <a href="#">
                        <img src="./images/img2.png" alt="">
                    </a>
                </div>
                <div class="item">
                    <a href="#">
                        <img src="./images/img3.png" alt="">
                    </a>
                </div>
                <div class="item">
                    <a href="#">
                        <img src="./images/img4.png" alt="">
                    </a>
                </div>
            </div>
            <!-- 上一张和下一张 -->
            <span class="next" id="next"></span>
            <span class="prev" id="prev"></span>
            <!-- 索引部分 -->
            <div class="slider_index" id="slider_index">
                <!-- js动态生成 -->
            </div>
        </div>
    </div>
    <script src="./js/myAnimation2.js"></script>
    <script src="./js/index.js"></script>
</body>
</html>

index.css

*{
    padding: 0;
    margin: 0;
}
.slider{
    width: 400px;
    height: 500px;
    margin: 100px auto;
    position: relative;
    overflow: hidden;
}
.slider_scroll {
    position: relative;
    width: 400px;
    height: 500px;
}
.slider_main{
    position: relative;
    width: 400px;
    height: 500px;
}
.slider_main .item{
    width: 40px;
    height: 500px;
    position: absolute;
}
.slider_main .item img{
    width: 400px;
    height: 500px;
}
/* 索引部分 */
.slider_index{
    width: 400px;
    height: 40px;
    line-height: 40px;
    text-align: center;
    color:#fff;
    font-weight: 700;
    z-index: 20;
    position: absolute;
    bottom: 0;
    background-color: rgba(0,0,0,.5);
}
.slider_index .slider_index_icon{
    margin: 0 10px;
    line-height: 40px;
    cursor: pointer;
}
.slider_index .slider_index_icon.current{
    color: red;
}
/* 下一张和上一张定位 */
.slider_scroll>span{
    position: absolute;
    width: 30px;
    height: 68px;
    background: url(../images/icon-slides.png) no-repeat;
    top: 50%;
    margin-top: -34px;
    cursor: pointer;
}
.slider_scroll span.next{
    right: 0;
    background-position: -46px 0;
}
.slider_scroll span.prev{
    left: 0;
    background-position: 0 0;
}

index.js

window.onload = function () {
    // 获取元素
    const slider = document.getElementById("slider");
    const slider_main = document.getElementById("slider_main");
    const slider_items = slider_main.children;
    
    const next = document.getElementById("next");
    const prev = document.getElementById("prev");

    const slider_index = document.getElementById("slider_index");
    
    let iNode = 0;  //当前显示索引的坐标  
    // 动态创建索引
    [...slider_items].forEach((v,i)=>{
        let span = document.createElement("span");
        span.innerText = i+1;
        // 给索引添加类
        if(i === 0){
            span.className = "slider_index_icon current"
        }else{
            span.className = "slider_index_icon"
        }

        slider_index.appendChild(span);
    })
    // 让滚动元素归位
    let scroll_w = this.parseInt(getStyle(slider,'width'));
    // console.log(scroll_w);
    [...slider_items].forEach((item,i,arr)=>{
        if(i !== 0){
            item.style.left = scroll_w + "px";
        }
    });
    // 下一步按钮
    function autoPlay() { 
        // 1.将显示的图片向左移动
        startAnimation(slider_items[iNode],{
            "left":-scroll_w
        });
        // 将下一张图片放在中心盒子的右边
        iNode++;
        if(iNode >= slider_items.length){
            iNode = 0;
        }
        // console.log(slider_items[iNode].left);
        slider_items[iNode].style.left = scroll_w + "px";
        // console.log(slider_items[iNode].left);
        // 将下一张图片向左移动
        startAnimation(slider_items[iNode],{
            "left":0
        });
        
        updateIndex();
     }
    next.onclick = autoPlay;
    // 更新索引样式
    let slider_index_items = slider_index.children;
    function updateIndex() {
        // console.log(slider_index_items);
        [...slider_index_items].forEach((item,i)=>{
            if(i == iNode){
                item.className = "slider_index_icon current";
            }else{
                item.className = "slider_index_icon"
            }
        })
    }
    //  上一步按钮
    prev.onclick = function () {
        // 1.将该元素右移动
        startAnimation(slider_items[iNode],{
            "left":scroll_w
        })
        // 2.将上一个元素放在左边
        iNode--;
        if(iNode < 0){
            iNode += slider_items.length
        }
        slider_items[iNode].style.left = -scroll_w + "px";
        // 3.将上一个元素右移
        startAnimation(slider_items[iNode],{
            "left":0
        })
        // 更新下面索引
        updateIndex();
    };
    // 设置索引点击事件
    [...slider_index_items].forEach((item,i)=> {
        item.onmousedown = function () {
            // 1.判断点击的索引与当前索引关系
            if(iNode > i){  // 上一张图片效果
                startAnimation(slider_items[iNode],{
                    "left":scroll_w
                })
                
                slider_items[i].style.left = -scroll_w + "px";


            }else if(iNode < i){  // 下一张图片效果
                startAnimation(slider_items[iNode],{
                    "left":-scroll_w
                })
                
                slider_items[i].style.left = scroll_w + "px";

            }
            iNode = i;
            startAnimation(slider_items[iNode],{
                "left":0
            })
            updateIndex();
        }
    });;
    // 设置自动播放
    let timer = window.setInterval(autoPlay,2000);
    // 设置鼠标悬浮停止定时器,离开开启定时器
    slider.onmouseover = function () {
        clearInterval(timer);
    }
    slider.onmouseout = function () {
        timer = window.setInterval(autoPlay,2000);
    }
}

图片部分,在上传到github上面时,已经将素材上传上去了。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐