816笔记(动画)

三大系列总结

element.offsetWidth  返回自身包括padding,边框,内容区的宽度,返回值不带单位
element.clientWidth  返回自身包括padding,内容区的宽度,不含边框,返回值不带单位
element.scrollWidth  返回自身实际的宽度,(padding占了就会算),不含边框,返回值不带单位

offset 用于获取元素的位置 offsetLeft offsetTop
client 用于获取元素的大小 clientWidth clientHeight
scroll 用于获取滚动的距离 scrollTop scrollLeft
页面滚动的距离 window.pageXOffset  window.pageYOffset

仿淘宝固定侧边栏

<body>
    <div class="slider-bar">
        <span class="goBack">返回顶部</span>
    </div>
    <div class="header w">头部区域</div>
    <div class="banner w">banner区域</div>
    <div class="main w">主体部分</div>

    <script>
        //1 获取元素
        var slidebar = document.querySelector('.slider-bar')
        var bar = document.querySelector('.banner')
        // banner.offsetTop banner元素距离body顶部的距离 要写到滚动的外面
        var bannerTop = banner.offsetTop
        // console.log(bannerTop)
        // 侧边栏固定定位之后应该变化的值
        var slidebarTop = sliderbar.offsetTop = bannerTop
        // console.log(slidebar.offsetTop)
        //获取main主体
        var main = document.querySelector('.main')
        var goBack = document.querySelector('.goBack')
        var mainTop = main.offsetTop
        // 页面滚动事件scroll
        document.addEventListener('scroll', function () {
            //window.pageYOffset    页面被卷走的高度   
            // 区别:element.scrollTop是元素被卷去的头部,不是页面
            //当我们页面被卷去的头部大于等于170 bannertop 侧边栏就要改为固定定位
            if (window.pageYOffset >= bannerTop) {
                slidebar.style.position = 'fixed'
                slidebar.style.top = slidebarTop
            } else {
                slidebar.style.position = 'absolute'
            }
            //当页面滚动到main盒子时,就显示goback
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block'
            } else {
                goBack.style.display = 'none'
            }
        })
    </script>

动画

实现原理

根据定时器setinterval()不断移动盒子位置

步骤:

  • 获取盒子当前位置
  • 让盒子在当前位置加上1个移动距离
  • 利用定时器不断地重复这个动作
  • 加一个结束定时器的条件
  • 元素需要添加定位才能使用element.style.left

分装匀速运动动画函数

    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }

        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: aquamarine;
        }
    </style>
</head>

<body>
    <div></div>
    <span>span</span>
    <script>
        //简单动画函数分装
        // 首先要有个目标对象obj  目标位置target time毫秒值
        function animate(obj, target, time) {
            var timer = setInterval(function () {
                if (oDiv.offsetLeft >= target) {
                    //停止定时器,停止动画
                    clearInterval(timer)
                }
                //匀速动画
                obj.style.left = obj.offsetLeft + 1 + 'px', time
            })
        }
        var oDiv = document.querySelector('div')
        animate(oDiv, 300, 50)
        var oSpan = document.querySelector('span')
        animate(oSpan, 300, 20)
    </script>

动画函数给不同元素记录不同的定时器

如果多个 元素都使用这个动画函数,每次都要var声明这个定时器,可以给不同的元素使用不同的定时器(自己专门用自己的定时器)

原理:我们可以很方便的给当前的对象添加属性

    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }

        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: aquamarine;
        }
    </style>
</head>

<body>
    <button>按钮</button>
    <div></div>
    <span>span</span>
    <script>

        function animate(obj, target, time) {
            var timer = setInterval(function () {
                if (oDiv.offsetLeft >= target) {
                    //停止定时器,停止动画
                    clearInterval(timer)
                }
                //匀速动画
                obj.style.left = obj.offsetLeft + 1 + 'px', time
            })
        }
        var oBtn = document.querySelector('button')
        var oDiv = document.querySelector('div')
        oBtn.onclick = function () {
            animate(oDiv, 500, 30)
        }
    </script>
    <script>
        function animate(obj, target, time) {
            //当我们不断地点击按钮,元素的速度会越来越快,因为我们开启了太多的定时器
            // 解决方案 让元素只有一个定时器执行
            // 先清除以前的定时器,只保留当前的一个定时器执行
            clearInterval(obj.timer)
            obj.timer = setInterval(function () {
                if (obj.offsetLeft >= target) {
                    //停止定时器,停止动画
                    clearInterval(obj.timer)
                }
                //匀速动画
                obj.style.left = obj.offsetLeft + 1 + 'px', time
            })
        }
        var oBtn = document.querySelector('button')
        var oDiv = document.querySelector('div')
        oBtn.onclick = function () {
            animate(oDiv, 500, 30)
        }
    </script>

缓动动画

实现原理

缓动动画就是让元素运动速度有所变化,最常见的就是让速度慢慢停下来

步骤

  • 让盒子每次移动的距离慢慢变小,速度就会慢慢停下来
  • 核心算法:(目标值-现在的位置)/10作为每次移动的距离步长
  • 停止条件:让当前盒子位置等于目标位置就停止定时器
  • 步长值要取整
    <style>
        div {
            position: absolute;
            left: 0;
            width: 100px;
            height: 100px;
            background-color: pink;
        }

        span {
            position: absolute;
            left: 0;
            top: 200px;
            display: block;
            width: 150px;
            height: 150px;
            background-color: aquamarine;
        }
    </style>
</head>

<body>
    <button>按钮</button>
    <div></div>
    <span>span</span>
    <script>
        function animate(obj, target) {
            clearInterval(obj.timer)
            obj.timer = setInterval(function () {
                //步长要写在定时器里面
                var step = (target - obj.offsetLeft) / 10
                //把每次加1这个步长值改为一个慢慢变小的值
                obj.style.left = obj.offsetLeft + step + 'px'
                if (obj.offsetLeft = target) {
                    //停止定时器,停止动画
                    clearInterval(obj.timer)
                }
            }, 30)
        }
        var oBtn = document.querySelector('button')
        var oDiv = document.querySelector('div')
        oBtn.addEventListener('click', function () {
            animate(oDiv, 500)
        })
        //匀速动画 盒子当前的位置+固定的值 1px
        //缓动动画 盒子当前的位置+变化的值(目标值-现在的位置)/10
    </script>

动画函数在多个目标值之间移动

可以让动画函数从800移动到500,还可以从500移动到800

步长可能是正值,也可能是负值

  • 是正值,步长就往大取整
  • 是负值,步长就往小取整
    <button>点击800</button>
    <button>点击500</button>
    <script>
        function animate(obj, target) {
            clearInterval(obj.timer)
            obj.timer = setInterval(function () {
                //步长要写在定时器里面
                var step = (target - obj.offsetLeft) / 10
                //步长可能是正值,也可能是负值 把步长值改为整数,不要出现小数问题
                step = step > 0 ? Math.ceil(step) : Math.floor(step)
                if (obj.offsetLeft === target) {
                    //停止定时器,停止动画
                    clearInterval(obj.timer)
                }
                obj.style.left = obj.offsetLeft + step + 'px'
            }, 30)
        }
        var oBtn = document.querySelector('button')
        var oDiv = document.querySelector('div')
        oBtn.addEventListener('click', function () {
            animate(oDiv, 800)
        })
        oBtn.addEventListener('click', function () {
            animate(oDiv, 500)
        })
    </script>

动画函数添加回调函数

回调函数,就是函数可以作为一个参数,将这个函数作为参数传到另一个函数里面,当那个函数执行完之后,再执行传进去的这个函数。这个过程就叫做回调。

回调函数写的位置就是定时器结束的位置。

    <button>点击800</button>
    <button>点击500</button>
    <script>
        function animate(obj, target, callback) {
            //callback=function(){}
            clearInterval(obj.timer)
            obj.timer = setInterval(function () {
                //步长要写在定时器里面
                var step = (target - obj.offsetLeft) / 10
                //步长可能是正值,也可能是负值 把步长值改为整数,不要出现小数问题
                step = step > 0 ? Math.ceil(step) : Math.floor(step)
                if (obj.offsetLeft === target) {
                    //停止定时器,停止动画
                    clearInterval(obj.timer)

                    //动画结束之后我们要做一些操作
                    // 就在定时器结束后使用回调函数
                    // 回调函数
                }
                if (callback) {
                    //调用函数
                    callback()
                }
                obj.style.left = obj.offsetLeft + step + 'px'
            }, 30)
        }
        var oBtn = document.querySelector('button')
        var oDiv = document.querySelector('div')
        oBtn.addEventListener('click', function () {
            animate(oDiv, 800, function () {
                alert(123)
            })
        })

        oBtn.addEventListener('click', function () {
            animate(oDiv, 500, function () {
                alert(234)
            })
        })
    </script>

posted on   星野落  阅读(18)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示