原生js返回顶部动画效果怎么实现?

项目背景:最近在做一个网站页面的改版,有一个返回顶部的功能需求,考虑怎么才能有更好一点的用户体验。

建议使用第二种实现方法

1. 第一种实现方法

转载 https://www.cnblogs.com/JosephBee/p/7326556.html

var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
document.body.style.marginTop = -scrollTop + "px";
document.body.scrollTop = 0;
document.body.style.transition = "all 1s ease-in-out";
document.body.style.marginTop = 0;
setTimeout(function() {
    
    
     document.body.style.transition = 'none';
}, 1000);

出现的问题:

返回之前的body没有任何style,返回之后出现style内联样式

在这里插入图片描述
在这里插入图片描述

解决方法:

setTimeout(function() {
    
    
        document.body.removeAttribute("style");
}, 1000);

不足:

  1. 这种实现方法会把滚动条直接滚动到顶部用户体验不如第二种好。
  2. 这种实现方法如果body存在自己的内联样式就会造成样式错乱。

第二种实现方法

转载 https://www.jb51.net/article/84967.htm

//页面加载后触发
window.onload = function(){
    
    
  var btn = document.getElementById('btn');
  var timer = null;
  var isTop = true;
  //获取页面可视区高度
  var clientHeight = document.documentElement.clientHeight;
  //滚动条滚动时触发
  window.onscroll = function() {
    
    
  //显示回到顶部按钮
    var osTop = document.documentElement.scrollTop || document.body.scrollTop;
    if (osTop >= clientHeight) {
    
    
      btn.style.display = "block";
    } else {
    
    
      btn.style.display = "none";
    };
  //回到顶部过程中用户滚动滚动条,停止定时器
    if (!isTop) {
    
    
      clearInterval(timer);
    };
    isTop = false;
  };
 
  btn.onclick = function() {
    
    
    //设置定时器
    timer = setInterval(function(){
    
    
      //获取滚动条距离顶部高度
      var osTop = document.documentElement.scrollTop || document.body.scrollTop;
      var ispeed = Math.floor(-osTop / 7);
       
      document.documentElement.scrollTop = document.body.scrollTop = osTop+ispeed;
      //到达顶部,清除定时器
      if (osTop == 0) {
    
    
        clearInterval(timer);
      };
      isTop = true; 
    },30);
  };
};

不足:

  1. 这种方法需要注意清空定时器。
  2. 代码比第一种多,逻辑较为复杂。

---------------------------------分割线-------------------------------------------

3. 自己项目

别直接抄我的代码 里面包含自己的业务逻辑,抄上也不能使用

<!-- 右侧悬浮框 -->
<template>
  <div class="awc-suspend">
    <ul class="awcs-list" :class="{
     
     'awcs-lbottom':isBottom}">
      <li class="awcs-item">
        <img src="./images/awcsuspendcb_canzhan.png" alt class="awcsi-img">
        <router-link to class="awcs-a">
          <span class="awcsi-text">参展</span>
        </router-link>
      </li>
      <li class="awcs-item">
        <img src="./images/awcsuspendcb_shangchuan.png" alt class="awcsi-img">
        <router-link to class="awcs-a">
          <span class="awcsi-text">作品</span>
        </router-link>
      </li>
      <li class="awcs-item">
        <img src="./images/awcsuspendcb_renzhen.png" alt class="awcsi-img">
        <router-link to class="awcs-a">
          <span class="awcsi-text">资料认证</span>
        </router-link>
      </li>
      <li class="awcs-item">
        <img src="./images/awcsuspendcb_weixin.png" alt class="awcsi-img">
        <router-link to class="awcs-a awcs-wxcode">
          <!-- <span class="awcsi-text">公众号</span> -->
          <div class="wxcode-mask">
            <div class="wxcode-icon"></div>
            <div class="wxcode-img">
              <img src="./images/awcsuspend-code.png" alt class="wxcode-img">
            </div>
            <div class="wxcode-title">微信扫一扫</div>
          </div>
        </router-link>
      </li>
      <li class="awcs-item awcs-back" v-if="suspendFlag" @click="backTop()">
        <img
          src="./images/awcsuspendcb_back.png"
          alt
          class="awcsi-img">
      </li>
    </ul>
  </div>
</template>

<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
export default {
     
     
  //import引入的组件需要注入到对象中才能使用
  components: {
     
     },
  data() {
     
     
    //这里存放数据
    return {
     
     
      // 悬浮框开关
      suspendFlag: false,
      // 返回顶部定时器
      scrollToptimer: null,
      // 是否到达顶部
      isTop: true,
      // 是否到达底部
      isBottom: false
    };
  },
  //监听属性 类似于data概念
  computed: {
     
     },
  //监控data中的数据变化
  watch: {
     
     },
  //方法集合
  methods: {
     
     
    // 返回顶部
    backTop() {
     
     
      const that = this;
      //设置定时器
      that.scrollToptimer = setInterval(() => {
     
     
        //获取滚动条距离顶部高度
        var osTop =
          document.documentElement.scrollTop || document.body.scrollTop;
        var ispeed = Math.floor(-osTop / 7);

        document.documentElement.scrollTop = document.body.scrollTop =
          osTop + ispeed;
        //到达顶部,清除定时器
        if (osTop == 0) {
     
     
          clearInterval(that.scrollToptimer);
        }
        that.isTop = true;
      }, 30);
    },
    backScroll() {
     
     
      const that = this;
      window.addEventListener("scroll", function() {
     
     
        //获取页面可视区高度
        var clientHeight = document.documentElement.clientHeight;
        var osTop =
          document.documentElement.scrollTop || document.body.scrollTop;
        //显示回到顶部按钮
        if (osTop >= clientHeight) {
     
     
          that.suspendFlag = true;
        } else {
     
     
          that.suspendFlag = false;
        }
        //回到顶部过程中用户滚动滚动条,停止定时器
        if (!that.isTop) {
     
     
          clearInterval(that.scrollToptimer);
        }
        // 判断是否即将到达底部 反正悬浮在底部状态栏上
        var bottomHeight = document.body.scrollHeight - 240;
        if (osTop + clientHeight >= bottomHeight) {
     
     
          that.isBottom = true;
        } else {
     
     
          that.isBottom = false;
        }
        that.isTop = false;
      });
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)
  created() {
     
     },
  //生命周期 - 挂载完成(可以访问DOM元素)
  mounted() {
     
     
    this.backScroll();
  },
  beforeCreate() {
     
     }, //生命周期 - 创建之前
  beforeMount() {
     
     }, //生命周期 - 挂载之前
  beforeUpdate() {
     
     }, //生命周期 - 更新之前
  updated() {
     
     }, //生命周期 - 更新之后
  beforeDestroy() {
     
     
    window.removeEventListener("scroll", this.backScroll);
  }, //生命周期 - 销毁之前
  destroyed() {
     
     }, //生命周期 - 销毁完成
  activated() {
     
     } //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style lang='less' scoped>
//@import url(); 引入公共css类
.awcs-list {
     
     
  width: 40px;
  position: fixed;
  bottom: 120px;
  margin-top: -225px;
  right: 0;
  z-index: 1001;
  transition: all 0.2s;
  .awcs-item {
     
     
    // width: 40px;
    height: 40px;
    display: flex;
    justify-content: center;
    flex-direction: column;
    background: #031c30;
    border-top: 1px solid #1b394b;
    box-sizing: border-box;
    cursor: pointer;
    position: relative;
  }
  .awcsi-img {
     
     
    width: 40px;
    height: 40px;
    padding:9px;
    box-sizing: border-box;
    margin: 0 auto;
    // padding: 7.5px;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
    background: #031c30;
  }
  .awcsi-text {
     
     
    color: #000;
    line-height: 16px;
    font-size: 14px;
  }
  .awcs-a {
     
     
    width: 86px;
    min-height: 38px;
    margin: 1px 0;
    line-height: 38px;
    box-shadow: 0px 1px 3px rgba(100, 96, 96, 0.16);
    position: absolute;
    left: 86px;
    top: 0px;
    transition: all 0.3s;
  }
  .awcs-item:hover > .awcs-a {
     
     
    left: -86px;
  }
  .awcs-wxcode{
     
     
    left: 96px;
    top: 4px;
  }
  .awcs-item:hover > .awcs-wxcode {
     
     
    left: -96px;
  }
  .wxcode-mask {
     
     
    width: 90px;
    height: 90px;
    padding: 5px 14px;
    padding-bottom: 0;
    box-sizing: border-box;
    background-color: #fff;
    overflow: hidden;
    text-align: center;
    box-shadow:0px 1px 3px rgba(100,96,96,0.16);  
  }
  .wxcode-icon{
     
     
    width: 8px;
    height: 8px;
    background: #fff;
    transform: rotateZ(45deg);
    position: absolute;
    right: -8px;
    top: 8px;
  }
  .wxcode-img {
     
     
    width: 64px;
    height: 64px;
    overflow: hidden;
  }
  .wxcode-title {
     
     
    font-size: 12px;
    line-height: 16px;
    color: #666666;
  }
}
.awcs-lbottom {
     
     
  bottom: 240px;
}
</style>

猜你喜欢

转载自blog.csdn.net/qq_15238979/article/details/90241304