首页 > 其他分享 >day17.运动(下)+轮播图 .笔记

day17.运动(下)+轮播图 .笔记

时间:2022-10-24 21:14:20浏览次数:109  
标签:index 轮播 笔记 element current day17 showBox key var

链式动画

就是动画执行完接另一个动画 , 不断的进行链接

封装进阶 ( 通过传入回调函数完成链式运动 )
// 0.缓冲运动的封装
// element表示元素,targetObj表示目标对象,callbackFn是回调函数,用来解决异步变成同步的
function bufferAnimation(element, targetObj, callbackFn) {
    // 1.判断是否有传入元素,没有就直接报错
    if (!element) {
        throw new Errow('元素不能少')
    }
    // 2.给元素设置一个定时器,以便后续动画的操作
    element.timer = setInterval(() => {
        // 3.设置默认所有的动画都是没问题的
        var flag = true
        // 4.遍历目标对象
        for (let key in targetObj) {
            // 5.取出当前样式值
            let current = parseFloat(getStyle(element)[key])
            // 6.取出目标值
            let target = targetObj[key]
            // 7.如果是宽高的变化
            if (key == 'width' || key == 'height' || key == 'top' || key == 'left') {
                // 8.那步长是负数就向下取整,正数就向上取整
                let step = target - current > 0 ? Math.ceil((target - current) / 10) : Math.floor((target - current) / 10)
                current += step
                // 9.设置样式
                element.style[key] = current + 'px'
            }
            // 10.如果是透明度的变化
            if (key == 'opacity') {
                // 11.它的步长也还是负树向下取整,正数向上取整,但是因为透明度最小是0,最大是1,所以要先放大,设置的时候再缩小
                let step = target - current > 0 ? Math.ceil((target - current) * 1000 / 10) : Math.floor((target - current) * 1000 / 10)
                current += step / 1000
                // 12.设置样式
                element.style[key] = current
            }
            // 13.如果是层高的变化,那它的样式就直接等于目标值
            if (key == 'zIndex') {
                element.style[key] = target
            }
            // 14.如果当前值不等于目标值,就是没有完成,返回false,定时器不会清除,效果也不会呈现
            if (current != target) {
                flag = false
            }
        }
        // 15.如果全部走完了,就清除定时器,显示效果
        if (flag) {
            clearInterval(element.timer)
            // 16.判断后面传入的参数是否为函数,是就调用
            if (typeof callbackFn == 'function') {
                callbackFn()
            }
        }
    }, 20)

}

实例 ( 先变化div的宽高再改变它的位置 )

<button>变变变</button>
<div></div>
<script src="./js/运动封装.js"></script>
<script>
    // 获取div和按钮
    var div = document.querySelector('div')
    var btn = document.querySelector('button')

    // 给按钮设置点击事件
    btn.onclick = function () {
        // 先让宽高变化,再变化位置
        // 调用缓冲动画(需求是有两个异步操作,在不知道那个异步先执行完的时候可以通过回调函数来解决异步问题,让异步变同步)
        buffer(div, { width: 666, height: 300 }, () => {
            // 变化位置
            buffer(div, { top: 200 }, () => {
                // 变化位置
                buffer(div, { left: 200 })
            })
        })
    }


</script>

轮播图

核心
  • 滚动切换 ( 更改的是大盒子的位置 )

  • 透明度切换 ( 更改的是图片的透明度 )

  • 图片切换 ( 直接变化图片的位置 )

滚动切换
  • 大盒子里面容纳多个图片 ,

  • 图片的大小和显示盒子的大小一致 ,

  • 大盒子的大小超出了显示盒子 ( 溢出隐藏 )

  • 根据切换的下标来控制大盒子的位置

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                list-style: none;
            }
            .showBox,
            li,
            img {
                width: 400px;
                height: 250px;
            }
            .showBox {
                margin: 200px auto;
                overflow: hidden;
            }
            ul {
                width: 800%;
                position: relative;
            }
            li {
                float: left;
            }
        </style>
    </head>
    <body>
        <div class="showBox">
            <ul>
                <li><img src="./images/slidepic1.jpg" alt=""></li>
                <li><img src="./images/slidepic2.jpg" alt=""></li>
                <li><img src="./images/slidepic3.jpg" alt=""></li>
                <li><img src="./images/slidepic4.jpg" alt=""></li>
                <li><img src="./images/slidepic5.jpg" alt=""></li>
                <li><img src="./images/slidepic6.jpg" alt=""></li>
                <li><img src="./images/slidepic7.jpg" alt=""></li>
                <li><img src="./images/slidepic8.jpg" alt=""></li>
            </ul>
        </div>
        <script src="./js/运动封装.js"></script>
        <script>
            // 滚动自动轮播
            // 1.获取显示的盒子和ul     
            var showBox = document.querySelector('.showBox')
            var ul = document.querySelector('ul')
            // 2.2获取图片的宽度
            var showBoxWidth = parseFloat(getStyle(showBox).width)
            // 2.封装一个自动轮播的方法
            function autoPlay() {
                // 2.1 根据下标来切换,设置默认下标为0
                var index = 0
                // 2.3 设置定时器,2秒切换下一张
                var timer = setInterval(() => {
                    index++
                    // 2.4 如果下标等于图片的长度了就切换成第一张图片
                    if (index == ul.children.length) {
                        index = 0
                    }
                    // 2.5 调用动画根据(下标*图片宽度*-1)来实现轮播
                    buffer(ul, { left: showBoxWidth * index * -1 })
                }, 2000)
                }
            // 3.调用自动轮播的方法
            autoPlay()
        </script>
    </body>
</html>

透明度切换

  • 所有的图叠在一起

  • 将前面图片的透明度设置为0,当前图片设置为1

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                padding: 0;
                margin: 0;
                list-style: none;
            }
            .showBox,
            li,
            img {
                width: 400px;
                height: 250px;
            }
            .showBox {
                margin: 200px auto;
                overflow: hidden;
            }
            .wrap {
                width: 800%;
            }
            li {
                float: left;
                opacity: 0;
                position: absolute;
            }
            ul>li:nth-child(1) {
                opacity: 1;
            }
        </style>
    </head>
    <body>
        <div class="showBox">
            <ul class="wrap">
                <li><img src="./images/slidepic1.jpg" alt=""></li>
                <li><img src="./images/slidepic2.jpg" alt=""></li>
                <li><img src="./images/slidepic3.jpg" alt=""></li>
                <li><img src="./images/slidepic4.jpg" alt=""></li>
                <li><img src="./images/slidepic5.jpg" alt=""></li>
                <li><img src="./images/slidepic6.jpg" alt=""></li>
                <li><img src="./images/slidepic7.jpg" alt=""></li>
                <li><img src="./images/slidepic8.jpg" alt=""></li>
            </ul>
        </div>
        <script src="./js/运动封装.js"></script>
        <script>
            // 获取ul
            var wrap = document.querySelector('.wrap')
            // 封装一个切换图片及设置透明度的方法
            function move() {
                // 设置默认的下标为0
                var index = 0
                // 切换图片的定时器
                var timer = setInterval(() => {
                    // 改透明度,先将切换前的全部设置为0
                    buffer(wrap.children[index], { opacity: 0 }, () => {
                        // 进行图片切换
                        index++
                        // 到了最后就切换到第一个
                        if (index == wrap.children.length) {
                            index = 0
                        }
                        // 再将自己的透明度改为1
                        buffer(wrap.children[index], { opacity: 1 })
                    })
                }, 2000)
                }
            // 调用方法
            move()
        </script>
    </body>
</html>

图片切换

 

  • 根据图片的编号来切换对应的图片
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                padding: 0;
                margin: 0;
                list-style: none;
            }

            .showBox,
            img {
                width: 400px;
                height: 250px;
            }

            .showBox {
                margin: 200px auto;

            }
        </style>
    </head>

    <body>
        <div class="showBox">
            <img src="./images/slidepic1.jpg" alt="">
        </div>
        <script src="./js/运动封装.js"></script>
        <script>
            // 获取图片
            var img = document.querySelector('.showBox img')
            // 封装一个移动的方法
            function move() {
                // 根据图片编号来切换和生成图片,默认为1
                var i = 1
                // 设置切换图片的定时器
                var timer = setInterval(() => {
                    i++
                    // 如果编号超出图片的编号就切换成第一张
                    if (i == 7) (
                        i = 1
                    )
                    // 设置图片地址
                    img.src = `./images/slidepic${i}.jpg`
                }, 2000)
                }
            // 调用自动移动的方法
            move()
        </script>
    </body>

无缝轮播 ( 滚动轮播的进阶 )

  • 拷贝第一张到最后

  • 判断是否到达最后一张,到了就设置到第一张的位置

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            .showBox,
            li {
                width: 400px;
                height: 250px;
            }
            li>img {
                width: 100%;
            }
            .showBox {
                margin: 200px auto;
                /* 溢出隐藏 */
                overflow: hidden;
            }
            ul {
                width: 800%;
                position: relative;
            }
            ul>li {
                list-style: none;
                float: left;
            }
        </style>
    </head>
    <body>
        <div class="showBox">
            <ul class="wrap">
                <li><img src="./images/slidepic1.jpg" alt=""></li>
                <li><img src="./images/slidepic2.jpg" alt=""></li>
                <li><img src="./images/slidepic3.jpg" alt=""></li>
                <li><img src="./images/slidepic4.jpg" alt=""></li>
                <li><img src="./images/slidepic5.jpg" alt=""></li>
                <li><img src="./images/slidepic6.jpg" alt=""></li>
                <li><img src="./images/slidepic7.jpg" alt=""></li>
            </ul>
        </div>
        <script src="./move.js"></script>
        <script>
            //获取显示盒子
            var showBox = document.querySelector('.showBox')
            //获取显示盒子的宽度
            var showWidth = parseFloat(getStyle(showBox).width)
            //获取ul(需要切换位置的容器)
            var wrap = document.querySelector('.wrap')
            //拷贝第一张图加到最后
            //克隆第一个li
            var firstLi = wrap.children[0].cloneNode(true)
            var i = 0
            //将克隆的元素加入到ul
            wrap.appendChild(firstLi)
            //封装一个autoMove的函数
            function autoMove() {
                //切换图片的定时器
                var timer = setInterval(() => {
                    move(wrap, showWidth)
                }, 2000)
                }
            // //调用自动移动的方法
            autoMove()//抽取方法 x轴移动 移动的元素 变化i值 移动的宽度 对应的方向(默认为正方向)
            function move(element, showWidth, isAsc = true) {
                if (isAsc) {
                    i++
                } else {
                    i--
                }
                //移动对应的ul 0 -400 -800
                //距离等于 当前下标*对应显示盒子的宽度*-1
                var distance = i * showWidth * -1
                //执行动画
                bufferAnimation(element, {
                    left: distance
                }, () => {
                    //到达最后下标
                    if (i == element.children.length - 1 && isAsc) {
                        //i的值重新变成0
                        i = 0
                    }
                    if (i == 0 && !isAsc) {
                        //立即设置位置 到第一张设置位置为最后一张
                        i = element.children.length - 1
                    }
                    //设置位置
                    element.style.left = i * showWidth * -1 + 'px'
                })
            }
        </script>
    </body>
</html>

升级版带焦点的轮播

  • html代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            .showBox,
            li {
                width: 400px;
                height: 250px;
            }
            li>img {width: 100%;
            }
            .showBox {
                position: relative;
                margin: 200px auto;
                /* 溢出隐藏 */
                overflow: hidden;
            }
            ul {
                width: 800%;
                position: relative;
            }
            ul>li {
                list-style: none;
                float: left;
            }
            .cirList {
                position: absolute;
                right: 20px;
                bottom: 10px;
                width: 150px;
            }
            .cirList>li {
                width: 10px;
                height: 10px;
                background-color: #fff;
                border-radius: 50%;
                margin: 0 5px;
            }
            .cirList .selected {
                background-color: red;
            }
            .arrow{
                display: none;
            }
            .arrow>a{
                display: block;
                width: 50px;
                height: 50px;
                position: absolute;
                top: 50%;
                margin-top: -25px;
            }
            .arrow>.prev{
                background: url(./images/prev.png) no-repeat center;
                background-size: contain;
                left: 0;
            }
            .arrow>.next{
                background: url(./images/next.png) no-repeat center;
                background-size: contain;
                right: 0;
            }
        </style>
    </head>
    <body>
        <div class="showBox">
            <ul class="wrap">
                <li><img src="./images/slidepic1.jpg" alt=""></li>
                <li><img src="./images/slidepic2.jpg" alt=""></li>
                <li><img src="./images/slidepic3.jpg" alt=""></li>
                <li><img src="./images/slidepic4.jpg" alt=""></li>
                <li><img src="./images/slidepic5.jpg" alt=""></li>
                <li><img src="./images/slidepic6.jpg" alt=""></li>
                <li><img src="./images/slidepic7.jpg" alt=""></li>
            </ul>
            <!-- 焦点 -->
            <ul class="cirList">
            </ul>
            <div class="arrow">
                <a href="" class="prev"></a>
                <a href="" class="next"></a>
            </div>
        </div>
        <script src="./move.js"></script>
        <script src="./carousel.js"></script>
    </body>
</html>
  • js代码
//获取显示盒子
var showBox = document.querySelector('.showBox')
//获取显示盒子的宽度
var showWidth = parseFloat(getStyle(showBox).width)
//获取ul(需要切换位置的容器)
var wrap = document.querySelector('.wrap')
//获取焦点的盒子
var cirList = document.querySelector('.cirList')
//获取箭头的盒子
var arrow = document.querySelector('.arrow')
//变化的下标
var i = 0
//焦点取值的下标
var index = 0
//定时器
var timer
//调用init的方法
init()
//调用自动移动的方法
autoMove()
//给showBox添加移入事件
showBox.onmouseenter = function () {
    //清除定时器
    clearInterval(timer)
    //显示箭头的盒子
    arrow.style.display = 'block'
}
//移出继续执行
showBox.onmouseleave = function () {
    //调用轮播
    autoMove()
    //隐藏
    arrow.style.display = 'none'
}
//给箭头添加事件
Array.from(arrow.children).forEach((v, i) => {
    v.onclick = (e) => {
        e = e || window.event
        //禁止a标签默认行为
        e.preventDefault();
        move(wrap, showWidth, i)
    }
})
//给cirList下面的li添加点击事件 事件委托机制
cirList.onclick = function (e) {
    e = e || window.event
    //判断当前操作的元素是否为li
    if (e.target.tagName == 'LI') {
        //获取当前点击的li的下标
        let clcikIndex = Array.from(cirList.children).findIndex((v) => {
            //如果当前操作的对象是遍历的对象那么返回出去
            return v == e.target
        })-1
        //改变对应位置及下标
        index = clcikIndex
        i = clcikIndex
        //调用move移动
        move(wrap, showWidth)
    }
}
//初始化生成焦点的方法
function init() {
    //拷贝之前生成对应的焦点
    Array.from(wrap.children).forEach((v, i) => {
        //在第一个焦点添加一个class名字为selected
        if (i == 0) {
            cirList.innerHTML += `<li class='selected'></li>`
        } else {
            //生成对应的焦点加入到cirList里面
            cirList.innerHTML += `<li></li>`
        }
    })
    //拷贝第一张图加到最后
    //克隆第一个li
    var firstLi = wrap.children[0].cloneNode(true)
    //将克隆的元素加入到ul
    wrap.appendChild(firstLi)
}
//封装一个autoMove的函数
function autoMove() {
    //切换图片的定时器
    timer = setInterval(() => {
        move(wrap, showWidth)
    }, 2000)
}
//封装一个焦点变化的函数 传入的index表示当前要设置的焦点
function changeCir(index) {
    //排他思维
    //先将所有的class清除
    Array.from(cirList.children).forEach((li) => {
        li.className = ''
    })
    //再给自己添加对应的样式
    cirList.children[index].className = 'selected'
}
//抽取方法 x轴移动 移动的元素 变化i值 移动的宽度 对应的方向(默认为正方向)
function move(element, showWidth, isAsc = true) {
    //先检索区间
    rangeCheck(element, isAsc)
    //再进行i值变化
    if (isAsc) {
        i++
        index++
    } else {
        i--
        index--
    }
    //焦点切换及区间检索
    rangeCheckCir(element)
    //执行动画
    //移动对应的ul 0 -400 -800
    //距离等于 当前下标*对应显示盒子的宽度*-1
    var distance = i * showWidth * -1
    bufferAnimation(element, {
        left: distance
    }, () => {
    })
}
//区间检索i下标
function rangeCheck(element, isAsc) {
    //到达最后下标
    if (i >= element.children.length - 1 && isAsc) {
        //i的值重新变成0
        i = 0
    }
    if (i <= 0 && !isAsc) {
        //立即设置位置 到第一张设置位置为最后一张
        i = element.children.length - 1
    }
    //设置位置
    element.style.left = i * showWidth * -1 + 'px'
}
//区间检索对应的焦点下标值
function rangeCheckCir(element) {
    //判断焦点下标
    if (index < 0) { //8张图 下标为 0-7 7个焦点 下标 0-6
        index = element.children.length - 2
    }
    if (index > element.children.length - 2) {
        index = 0
    }
    //更改焦点
    changeCir(index)
}

辅助代码 (move.js)

//缓冲运动封装
//element表示当前的元素 target表示目标对象 callbackFn表示传入的回调函数
function bufferAnimation(element, targetObj,callbackFn) {
    //如果element为undefined就直接报错
    if(!element){
        throw new Error('元素不能缺少')
    }
    //清除上一个定时器影响 (保证只有一个定时器)
    clearInterval(element.timer)
    //给元素对象添加一个属性为timer他是一个定时器
    element.timer = setInterval(() => {
        var flag = true
        //遍历对象
        for (let key in targetObj) {
            //取出当前值
            let current = parseFloat(getStyle(element)[key])
            //取出目标值
            let target = targetObj[key]
            //判断当前如果是位置的变化及对应的宽度高度的变化
            if(key=='width' || key == 'height' || key == 'left' || key == 'top')
            {
                //步长 负值向下取整 正值向上取整
                var step = target-current>0?Math.ceil((target - current) /
                                                      10):Math.floor((target - current) / 10)
                current += step
                element.style[key] = current + 'px'
            }
            //如果是透明度的变化
            if(key == 'opacity'){
                //步长 负值向下取整 正值向上取整
                var step = target-current>0?Math.ceil((target - current) * 1000
                                                      / 10):Math.floor((target - current)*1000 / 10)
                current += step / 1000
                element.style[key] = current
            }
            //如果是层高直接赋值
            if(key == 'zIndex'){
                element.style[key] = target
            }
            //如果没有完成就是false
            if(current != target){
                flag = false
            }
        }
        //如果全部走完了就清除
        if(flag){
            clearInterval(element.timer)
            //调用回调函数 如果传入的参数是函数
            if(typeof callbackFn == 'function'){
                callbackFn()
            }
        }
    },0)
}
//封装一个方法获取对应的样式(获取所有的样式)
function getStyle(element) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(element, '')
    } else {
        return element.currentStyle
    }
}

重点

  • 逻辑的掌握

  • dom操作

  • 定时器操作

  • 错误的解决

  • 定时器里面套定时器 ( 如果外面的执行时间要比里面的短 会导致里面的定时器无法被清除 (定时器

  • 的作用范围内要清除对应的定时器) )

  • 知识点的运用

  • 封装 (函数封装 抽取共同点)

  • 同步和异步 (通过回调函数解决 定时器是异步的 事件也是异步的)

第三方动画的js

move.js

github地址 : https://github.com/visionmedia/move.js

<div class="box"></div>
<div class="mybox"></div>
<script src='https://cdn.bootcdn.net/ajax/libs/move.js/0.5.0/move.js'></script>
<script>
    move('.box')
        .to(500, 200) //位置改变 x为500 y为200
        .rotate(180) //旋转180deg
        .scale(.5) //缩小0.5倍
        .set('background-color', '#888')//背景颜色
        .set('border-color', 'black')//边框颜色
        .duration('2s')//执行时间
        .skew(50, -10) //偏移
        .then() //成功
    // .set('opacity', 0) //透明度为0
        .duration('0.3s') //时间
        .scale(0.1) //缩小
        .pop() //加上他才能执行颜色设置相关的内容
        .end(); //动画结束
    //背景颜色变成绿色
    // 位置 变成 300 300
    // 旋转 180deg
    // 上面做完 放大2倍
    move('.mybox')
        .to(500,500)
        .set('background-color', 'hotpink')
        .rotate(180)
        .duration('3s')
        .then().scale(2).duration('11s').pop().end()
</script>
  animated.css (封装了css3的动画效果) 官网 : https://animate.style/   swiper.js (封装轮播图) 官网:https://www.swiper.com.cn/index.html

 

 

标签:index,轮播,笔记,element,current,day17,showBox,key,var
From: https://www.cnblogs.com/itlulu/p/16823004.html

相关文章

  • CISAW风险管理学习笔记(3)-风险管理标准体系
    个人学习总结,CISAW学习笔记之风险管理标准体系:......
  • MySQL 读书笔记(一)
    1MySQL表1.1索引组织表在InnoDB存储引擎中,表都是根据主键顺序存放的,这种存储方式称为索引组织表。InnoDB存储引擎中,每张MySQL表都有一个唯一主键,如果创建表时......
  • vue 笔记12 vue-router路由2 导航守卫
              Vue被创建,挂载,更新时调用函数。      网页标题                    登录......
  • day17 MySQL的安装 & 数据库基本语法——增删改查
    day17MySQL登录数据库mysql-hlocalhost-P3307-uroot-p查看所有数据库showdatabases;退出数据库exit;//现有表格usesitu;//使用哪个数据库createtable......
  • 传习录 散笔记
    良知:生命情感,生命感受.良知及天理,天道就在生命实践中(天人合一)    不是大脑认识的道德标准,而是本身的条例我善养吾浩然之气心安否意:情感喜怒悲惧......
  • C++编程笔记(QT)
    目录入门基础模态对话框消息提示框(messagebox)文件和目录字体选择框输入对话框进度条工具栏控件布局Windows托盘案例控件button下拉菜单按钮`radioButton`单选按钮......
  • ABBAC900F学习笔记159:报表1
    ABBAC900F学习笔记159:报表1_来自金沙江的小鱼_新浪博客(sina.com.cn)上面是我在新浪博客的链接,为了避免服务关闭,我在这里也记录一份终于来到这个知识点了。这里的学习是......
  • Asp.net MVC学习笔记(1)
       时隔多年又重新回到了这里,仿佛遇到了一个轮回。蓦然回首,15年开始对码农这个行业失望透顶,拿着4000多点工资没日没夜的写这各种增删改查,既没有精神上的成就感也没有......
  • ABBAC900F学习笔记157:再学习日志功能
    ABBAC900F学习笔记157:再学习日志功能_来自金沙江的小鱼_新浪博客(sina.com.cn)上面是我在新浪博客的链接,为了避免服务关闭,我在这里也记录一份前面一段时间学习过freelan......
  • ABBAC900F学习笔记158:日志功能2
    ABBAC900F学习笔记158:日志功能2_来自金沙江的小鱼_新浪博客(sina.com.cn)上面是我在新浪博客的链接,为了避免服务关闭,我在这里也记录一份。接着前面一篇来,知识点还是来自......