【react+ts】react+ts多种方法实现返回顶部demo

本文主要使用了以下方法来实现此功能

(1). [react方式]利用定时器requestAnimationFrame来实现

    let timer: number = 1000;
    /* 方法一:利用性能最好的定时器requestAnimationFrame来实现 */
    cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(oTop > 0){
            document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }
    });

(2). [react方式]利用html自带的方法scrollTo来实现

/* 方法二:利用html自带的方法来实现 */
scrollTo({top:0,behavior:'smooth'});

(3). [react方式]方法1和方法2的结合版

let timer: number = 1000;
cancelAnimationFrame(timer);
    timer = requestAnimationFrame(function fn(){
        var oTop = document.body.scrollTop || document.documentElement.scrollTop;
        if(oTop > 0){
    // eslint-disable-next-line no-restricted-globals
            scrollTo(0,oTop-50);
            timer = requestAnimationFrame(fn);
        }else{
            cancelAnimationFrame(timer);
        }
    });

(4). [react+ts]利用定时器requestAnimationFrame和运动来实现

count: number = 0;
start: number = 0;
dis: number = 0;
timer: number = 0;    /* 方法4类型 */
n: number = 0;
step: number = 0;
cur: number = 0;

cancelAnimationFrame(this.timer);
  this.start = document.body.scrollTop || document.documentElement.scrollTop; //  开始的位置
  this.count = Math.floor(1000 / 30); //次数
  this.dis = 0 - this.start; //
  this.n = 0;
  this.timer = requestAnimationFrame(this.func.bind(this, this.n,this.count));


func(n:number,count:number):void {
    n++;
    this.step = 1 - n / count; //步长
    this.cur = this.start + this.dis * (1 - this.step * this.step * this.step); //每次移动的距离
    document.documentElement.scrollTop = document.body.scrollTop = this.cur;
    this.timer = requestAnimationFrame(this.func.bind(this,n,count));
    if (n === count) {
      cancelAnimationFrame(this.timer);
    }

(5).[react+ts]利用定时器setInterval来实现

count: number = 0;
start: number = 0;
dis: number = 0;
n: number = 0;
step: number = 0;
cur: number = 0;
timer?: NodeJS.Timeout;

if (this.timer) clearInterval(this.timer);
this.start = document.body.scrollTop || document.documentElement.scrollTop; //  开始的位置
this.count = Math.floor(1000 / 30); //次数
this.dis = 0 - this.start; //要移动的距离
this.n = 0; //清零
this.timer = setInterval(this.func.bind(this), 30); //定义定时器,调用返回顶部方法

func() {
    this.n++; //移动次数自增
    this.step = 1 - this.n / this.count; //步长
    this.cur = this.start + this.dis * (1 - this.step * this.step * this.step); //每次移动的距离
    document.documentElement.scrollTop = document.body.scrollTop = this.cur; //设置当前滚动的距离
    if (this.n === this.count) {
      if (this.timer) clearInterval(this.timer);
    }
  }

整个项目代码:

import React, { Component } from "react";
import "./backToTop.less";

export default class Home extends Component {
  count: number = 0;
  start: number = 0;
  dis: number = 0;
  // timer: number = 0;    /* 方法4类型 */
  n: number = 0;
  step: number = 0;
  cur: number = 0;
  timer?: NodeJS.Timeout;
  oDiv?: HTMLElement;
  componentDidMount() {
    document.addEventListener("scroll", () => {
      if (
        document.documentElement.clientHeight +
          document.documentElement.scrollTop >
        document.documentElement.scrollHeight - 200
      ) {
        this.oDiv = document.querySelector(".fixed") as HTMLElement;
        if (this.oDiv) this.oDiv.style.display = "block";
      } else { if (this.oDiv) this.oDiv.style.display = "none";}
    });
  }

  backTop() {
    // let timer: number = 1000;
    // /* 方法一:利用性能最好的定时器requestAnimationFrame来实现 */
    // cancelAnimationFrame(timer);
    // timer = requestAnimationFrame(function fn(){
    //     var oTop = document.body.scrollTop || document.documentElement.scrollTop;
    //     if(oTop > 0){
    //         document.body.scrollTop = document.documentElement.scrollTop = oTop - 50;
    //         timer = requestAnimationFrame(fn);
    //     }else{
    //         cancelAnimationFrame(timer);
    //     }
    // });
    /* 方法二:利用html自带的方法来实现 */

    // eslint-disable-next-line no-restricted-globals
    // scrollTo({top:0,behavior:'smooth'});

    /* 方法三:1和2的结合版 */
    // cancelAnimationFrame(timer);
    // timer = requestAnimationFrame(function fn(){
    //     var oTop = document.body.scrollTop || document.documentElement.scrollTop;
    //     if(oTop > 0){
    // // eslint-disable-next-line no-restricted-globals
    //         scrollTo(0,oTop-50);
    //         timer = requestAnimationFrame(fn);
    //     }else{
    //         cancelAnimationFrame(timer);
    //     }
    // });

    /* 方法4:时间版运动 */
    /* cancelAnimationFrame(this.timer);
    this.start = document.body.scrollTop || document.documentElement.scrollTop; //  开始的位置
    this.count = Math.floor(1000 / 30); //次数
    this.dis = 0 - this.start; //
    this.n = 0;
    this.timer = requestAnimationFrame(this.func.bind(this, this.n,this.count)); */

    /* 方法5:setInterval */
    if (this.timer) clearInterval(this.timer);
    console.log(
      document.documentElement.scrollHeight,
      document.documentElement.scrollTop + document.documentElement.clientHeight
    );

    this.start = document.body.scrollTop || document.documentElement.scrollTop; //  开始的位置
    this.count = Math.floor(1000 / 30); //次数
    this.dis = 0 - this.start; //要移动的距离
    this.n = 0; //清零
    this.timer = setInterval(this.func.bind(this), 30); //定义定时器,调用返回顶部方法
  }
  /* 方法4函数 */
  /* func(n:number,count:number):void {
    n++;
    this.step = 1 - n / count; //步长
    this.cur = this.start + this.dis * (1 - this.step * this.step * this.step); //每次移动的距离
    document.documentElement.scrollTop = document.body.scrollTop = this.cur;
    this.timer = requestAnimationFrame(this.func.bind(this,n,count));
    if (n === count) {
      cancelAnimationFrame(this.timer);
    } */
  /* 方法5函数 */
  func() {
    this.n++; //移动次数自增
    this.step = 1 - this.n / this.count; //步长
    this.cur = this.start + this.dis * (1 - this.step * this.step * this.step); //每次移动的距离
    document.documentElement.scrollTop = document.body.scrollTop = this.cur; //设置当前滚动的距离
    if (this.n === this.count) {
      if (this.timer) clearInterval(this.timer);
    }
  }

  render() {
    return (
      <div className="back-to-top">
        <div className="container">
          <h3 className="center"> 返回顶部页面</h3>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
          <p>test 测试</p>
        </div>
        <div className="fixed" onTouchStart={this.backTop.bind(this)}>
          <div className="back">返回顶部</div>
        </div>
      </div>
    );
  }
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星召唤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值