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
})