分片加载
通过setTimeout
进行分片渲染
<ul>
</ul>
<script>
const ul = document.querySelector('ul')
const list = []
for (let i = 0; i < 100000; i++) {
list.push(i)
}
let num = 0
const size = 100
const count = Math.ceil(list.length / size)
const render = () => {
if (num >= count) return
setTimeout(() => {
for (let i = num * size; i < (num + 1) * size; i++) {
const li = document.createElement('li')
li.innerHTML = list[i]
ul.appendChild(li)
}
render(num++)
}, 0)
}
render(num)
</script>
文档碎片
通过document.createDocumentFragment()
创建文档碎片的方式,将创建的元素塞进文档碎片,在添加到页面上,文档碎片参考:https://developer.mozilla.org/zh-CN/docs/Web/API/Document/createDocumentFragment
<ul>
</ul>
<script>
const ul = document.querySelector('ul')
const bottom = document.querySelector('.bottom')
const list = []
for (let i = 0; i < 100000; i++) {
list.push(i)
}
let num = 0
const size = 100
const count = Math.ceil(list.length / size)
const render = () => {
if (num >= count) return
setTimeout(() => {
const fragment = document.createDocumentFragment()
for (let i = num * size; i < (num + 1) * size; i++) {
const li = document.createElement('li')
li.innerHTML = list[i]
fragment.appendChild(li)
}
ul.appendChild(fragment)
render(num++)
}, 0)
}
render(num)
懒加载
通过IntersectionObserver
方法判断给定元素是否出现在可是区域内,出现的话在进行追加数据
<ul>
<li class="bottom"></li>
</ul>
<script>
const ul = document.querySelector('ul')
const bottom = document.querySelector('.bottom')
const list = []
for (let i = 0; i < 100000; i++) {
list.push(i + 1)
}
let num = 0
const size = 100
const count = Math.ceil(list.length / size)
const render = () => {
if (num >= count) return
setTimeout(() => {
const fragment = document.createDocumentFragment()
for (let i = num * size; i < (num + 1) * size; i++) {
const li = document.createElement('li')
li.innerHTML = list[i]
fragment.appendChild(li)
}
ul.insertBefore(fragment, bottom)
}, 0)
}
const intersectionObserver = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting) {
render(num++)
}
})
intersectionObserver.observe(bottom)
render(num)
</script>
上拉加载
通过监听是否触底(滚动条距离顶部高度 + 可视区内容高度 >= 实际内容的高度)来进行数据加载
<div class="container">
<ul>
</ul>
</div>
<script>
const container = document.querySelector('.container')
const ul = document.querySelector('ul')
const list = []
for (let i = 0; i < 100000; i++) {
list.push(i + 1)
}
let num = 0
const size = 100
const count = Math.ceil(list.length / size)
const handleScroll = () => {
// 滚动条距离顶部高度 + 可视区内容高度 >= 实际内容的高度
if (container.scrollTop + container.clientHeight >= ul.clientHeight) {
num++
if (num >= count) {
container.removeEventListener('scroll', handleScroll)
return
}
createLi(num)
}
}
const createLi = (num) => {
for (let i = num * size; i < (num + 1) * size; i++) {
const li = document.createElement('li')
li.innerHTML = list[i]
ul.appendChild(li)
}
}
createLi(num)
// 节流函数
const debounce = (fn, delay) => {
let timer = null
return () => {
if (timer) clearTimeout(timer)
timer = setTimeout(fn, delay)
}
}
const debounceScroll = debounce(handleScroll, 300)
container.addEventListener('scroll', debounceScroll)
</script>