Web APIs---14. PC端网页特效(4)

案例1:返回顶部


在之前函数的基础上添加的第五部分

<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 sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        //被卷去头部的大小  一定要写在滚动的外面
        var bannerTop = banner.offsetTop; //offsetTop返回元素相对于带有定位的父元素的上方的偏移

        //改为固定定位后侧边栏会跳一下,这是由于侧边栏样式中的top: 300px;导致的。解决方案如下:
        var sliderbarTop = sliderbar.offsetTop - bannerTop;

        //获取元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');

        var mainTop = main.offsetTop;
        console.log(mainTop);


        //2. 添加页面滚动事件  页面滚动所以必须为document添加
        document.addEventListener('scroll', function() {
                //window.pageYOffset 页面被卷去的头部
                // console.log(window.pageYOffset); //检测得到172px的时候比较适合 将侧边栏改为固定定位
                //3. 当banner滚动到页面顶部时,侧边栏改为固定定位
                if (window.pageYOffset >= bannerTop) {
                    sliderbar.style.position = 'fixed';
                    //改为固定定位后侧边栏会跳一下,这是由于侧边栏样式中的top: 300px;导致的。解决方案如下:
                    sliderbar.style.top = sliderbarTop + 'px';
                } else {
                    sliderbar.style.position = 'absolute';
                    sliderbar.style.top = '300px'; //变成绝对定位后再将top值复原为300px
                }

                //4.当main滚动到页面顶部时,侧边栏出现返回顶部字样
                if (window.pageYOffset >= mainTop) {
                    goBack.style.display = 'block';
                } else {
                    goBack.style.display = 'none';
                }
            })
            //5.当我们点击了返回顶部模块,就让窗口滚动到页面的最上方
        goBack.addEventListener('click', function() {
            //
            window.scroll(0,0);
        })
    </script>
</body>

上述代码中,点击返回顶部页面是刷的一下就返回了顶部,现在希望返回顶部的过程柔和一点,添加返回顶部动画animate.js


但是需要对animate.js做一系列修改:

  • 盒子左右走改为页面上下滚动:将obj.offsetLeft修改为window.pageYOffset。
  • 盒子移动的位置改为页面滚动到的位置:将obj.style.left修改为window.scroll(x,y)
<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 sliderbar = document.querySelector('.slider-bar');
        var banner = document.querySelector('.banner');
        //被卷去头部的大小  一定要写在滚动的外面
        var bannerTop = banner.offsetTop; //offsetTop返回元素相对于带有定位的父元素的上方的偏移

        //改为固定定位后侧边栏会跳一下,这是由于侧边栏样式中的top: 300px;导致的。解决方案如下:
        var sliderbarTop = sliderbar.offsetTop - bannerTop;

        //获取元素
        var main = document.querySelector('.main');
        var goBack = document.querySelector('.goBack');

        var mainTop = main.offsetTop;
        console.log(mainTop);


        //2. 添加页面滚动事件  页面滚动所以必须为document添加
        document.addEventListener('scroll', function() {
            //window.pageYOffset 页面被卷去的头部
            // console.log(window.pageYOffset); //检测得到172px的时候比较适合 将侧边栏改为固定定位
            //3. 当banner滚动到页面顶部时,侧边栏改为固定定位
            if (window.pageYOffset >= bannerTop) {
                sliderbar.style.position = 'fixed';
                //改为固定定位后侧边栏会跳一下,这是由于侧边栏样式中的top: 300px;导致的。解决方案如下:
                sliderbar.style.top = sliderbarTop + 'px';
            } else {
                sliderbar.style.position = 'absolute';
                sliderbar.style.top = '300px'; //变成绝对定位后再将top值复原为300px
            }

            //4.当main滚动到页面顶部时,侧边栏出现返回顶部字样
            if (window.pageYOffset >= mainTop) {
                goBack.style.display = 'block';
            } else {
                goBack.style.display = 'none';
            }
        })

        //5.当我们点击了返回顶部模块,就让窗口滚动到页面的最上方
        goBack.addEventListener('click', function() {
            // window.scroll(0, 0);
            animate(window, 0); //
        })


        //缓动动画函数
        function animate(obj, target, callback) {
            // console.log(callback);  callback = function() {}  调用的时候 callback()

            // 先清除以前的定时器,只保留当前的一个定时器执行
            clearInterval(obj.timer);
            obj.timer = setInterval(function() {
                // 步长值写到定时器的里面
                // 把我们步长值改为整数 不要出现小数的问题
                // var step = Math.ceil((target - obj.offsetLeft) / 10);
                var step = (target - window.pageYOffset) / 10;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                if (window.pageYOffset == target) {
                    // 停止动画 本质是停止定时器
                    clearInterval(obj.timer);
                    // 回调函数写到定时器结束里面
                    // if (callback) {
                    //     // 调用函数
                    //     callback();
                    // }
                    callback && callback();
                }
                // 把每次加1 这个步长值改为一个慢慢变小的值  步长公式:(目标值 - 现在的位置) / 10
                // obj.style.left = window.pageYOffset + step + 'px';
                window.scroll(0, window.pageYOffset + step);
            }, 15);
        }
    </script>
</body>
//window.pageXOffset,window.pageYOffset     类似于元素的ele.offfsetTOP,ele.offfsetLeft
//window.scroll(x,y)    类似于元素的ele.style.left,ele.style.top

案例2:筋斗云案例

  • 案例需求
  • 案例分析
  • 结构代码
<body>
    <div id="c_nav" class="c-nav">
        <span class="cloud"></span>
        <ul>
            <li class="current"><a href="#">首页新闻</a></li>
            <li><a href="#">师资力量</a></li>
            <li><a href="#">活动策划</a></li>
            <li><a href="#">企业文化</a></li>
            <li><a href="#">招聘信息</a></li>
            <li><a href="#">公司简介</a></li>
            <li><a href="#">我是佩奇</a></li>
            <li><a href="#">啥是佩奇</a></li>
        </ul>
    </div>
</body>
  • JS代码
<script src="animate.js"></script>
<script>
    window.addEventListener('load', function() {
        //1. 获取元素
        var cloud = document.querySelector('.cloud');
        var c_nav = document.querySelector('.c-nav');
        var lis = c_nav.querySelectorAll('li');
        //2. 给所有的小li绑定事件
        //current作为筋斗云的起始位置
        var current = 0;
        for (var i = 0; i < lis.length; i++) {
            //(1)鼠标经过把 当前小li的位置作为目标值target
            lis[i].addEventListener('mouseenter', function() {
                animate(cloud, this.offsetLeft);
            });
            //(2)鼠标离开就复原为当前位置
            lis[i].addEventListener('mouseleave', function() {
                animate(cloud, current);
            });
            //(3)当我们鼠标点击,就把当前的位置作为目标值
            lis[i].addEventListener('click', function() {
                current = this.offsetLeft;
            });
        }
    })
</script>
原文地址:https://www.cnblogs.com/deer-cen/p/12310668.html