滚动加载+回到顶部功能实现,带节流

本文介绍了如何使用HTML和CSS实现页面滚动到底部加载更多内容的机制,并利用JavaScript节流函数优化滚动事件处理。同时,通过CSS创建了‘回到顶部’按钮,当页面滚动一定距离时固定显示,点击可返回页面顶部。此外,详细解释了滚动相关的重要属性如clientHeight、scrollTop和scrollHeight的含义和应用。
摘要由CSDN通过智能技术生成

HTML部分,给img设置data-src是为了方便实现加载的函数去拿到数据。

CSS部分,”回到顶部“做了一个fixed定位,调了个正方形的效果。

节流

我的理解是,从宏任务队列的角度理解,节流就是遇到一个新任务,直接丢弃新任务;防抖则是遇到一个新任务,就丢弃旧任务,让新任务进队列。这里只写了节流。thisArg是为了允许调用一个对象的成员函数。

用法

let throttleLoad = throttle(loader.loadMore, 300, loader)
window.addEventListener('scroll', throttleLoad)

加载更多

  • document.documentElement.clientHeight表示浏览器窗口可视区(不包括控制台等)的高度。假设控制台是水平方向的,你去拉伸控制台,这玩意会变。
  • document.documentElement.scrollTop表示当前你滚动到的位置离顶部有多远。
  • document.documentElement.scrollHeight表示当前可供滚动的高度共有多少。你滚到最底下的时候,可以发现scrollTop和scrollHeight还相差一个clientHeight。

上面是为方便理解而说的口水话,参考:https://blog.csdn.net/qq_33036599/article/details/81224346

所以scrollHeight-(scrollTop+clientHeight)可以得到离底部有多少距离(注:如果我的理解有误可以评论区告诉我qwq)。这里设置的是离底部100px就加载更多。

HTML+CSS

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>滚动加载更多</title>
  <!--<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>-->
  <!-- <script src="https://cdn.staticfile.org/vue/2.5.2/vue.min.js"></script> -->
  <style>
    body{
      margin: 0;
    }
    .container{
      width: 100%;
    }
    .img-area{
      margin-top: 40px;
      text-align: center;
    }
    .to-top-wrap{
      background-color: skyblue;
      font-size: 26px;
      color: white;
      text-align: center;
      padding: 12px;
      max-width: 69px;/* 字体26px,两行显示时,内容高度是69px,因此设置为和高度一样 */
      cursor: pointer;
      position: fixed;
      bottom: 150px;
      right: 80px;
    }
    .to-top-wrap:hover{
      background-color: deepskyblue;
    }
  </style>
</head>
<body>
<main class="container">
  <section class="img-area">
    <img class="my-photo" class="my-photo" data-src="./imgs/img1.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img2.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img3.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img4.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img5.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img6.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img7.png" />
  </section>
  <section class="img-area">
    <img class="my-photo" data-src="./imgs/img8.png" />
  </section>
</main>
<div class="to-top-wrap">
  回到顶部
</div>
<script src="./加载更多+回到顶部.js"></script>
</body>
</html>

JS

"use strict";

function throttle(fn, interval, thisArg, ...args) {
  let waiting = false
  return function () {
    if (waiting) return
    waiting = true
    setTimeout(() => {
      fn.apply(thisArg, args)
      waiting = false
    }, interval)
  }
}

class Loader {
  constructor() {
    this.idx = 0
    this.imgs = document.querySelectorAll('.my-photo')
  }

  loadImg(el) {
    if (this.idx >= this.imgs.length) return
    if (!el) {
      let img = this.imgs[this.idx]
      img.src = img.dataset.src
      return
    }
    if (!el.src) el.src = el.dataset.src
  }

  initImgs() {
    for (; this.idx < Math.min(2, this.imgs.length); ++this.idx) {
      this.loadImg()
    }
  }

  loadMore() {
    const clientHeight = window.innerHeight ? window.innerHeight : document.documentElement.clientHeight
    const scrollTop = document.documentElement.scrollTop
    const scrollHeight = document.documentElement.scrollHeight
    if (clientHeight + scrollTop + 100 >= scrollHeight) {
      this.loadImg()
      if (this.idx < this.imgs.length) this.idx++
    }
  }
}

let loader = new Loader()
loader.initImgs()
let throttleLoad = throttle(loader.loadMore, 300, loader)
window.addEventListener('scroll', throttleLoad)

let toTop = document.querySelector('.to-top-wrap')
toTop.addEventListener('click', () => {
  document.documentElement.scrollTop = 0
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值