参考资料
这里的下拉加载是翻页的代替,
即首次加载10条数据,当用户翻到最后一条数据后,自动加载数据实现翻页效果
不是移动端的下拉刷新(无需监听手势
way1
实现思路:
1、监听页面的用户的滚动事件,
当用户翻到了底部(内容页的底部) 就新加载数据
同时注意:1、节流 2、需要一个标识位,当加载数据时 监听无效
// 节流函数
$(document).scroll(function () {
if (($(document).scrollTop() + window.innerHeight === $(document).height())
&& window.scrollTag === undefined
)
{
window.scrollTag = true;
// 显示loading效果
$('.question-list-loading').html('<i class="iknow-icons"></i><span>加载中</span>');
this.getdata()
.then(res=>{
window.scrollTag = false;
})
}
way2
优化:
if (($(document).scrollTop() + window.innerHeight === $(document).height())
===》 某元素在可视区域了怎么判断
let scrTop = getTop();
let windowHeight = document.documentElement.clientHeight;
function getTop() {
return document.documentElement.scrollTop || document.body.scrollTop;
}
function getOffset(node) {
return node.getBoundingClientRect().top + scrTop;
}
function inView(node) {
// 设立阈值
const threshold = 0;
const viewTop = scrTop;
const viewBot = viewTop + windowHeight;
const nodeTop = getOffset(node);
const nodeBot = nodeTop + node.offsetHeight;
const offset = (threshold / 100) * windowHeight;
console.log((nodeBot >= viewTop - offset), (nodeTop <= viewBot + offset))
return (nodeBot >= viewTop - offset) && (nodeTop <= viewBot + offset)
}
way3
下拉到底部之后发送ajax异步请求,成功之后的回调里进行页面拼接
存在的问题:
1、图片:
当加载后的内容插入到页面中时,浏览器就开始获取图片。这意味着所有的图像同时下载,浏览器中的下载通道将被占满。同时,由于内容优先于用户浏览而加载,所以可能被迫下载底部那些永远也不会被用户浏览到的图像。
解决思路:
即一次性请求下一页的10个也是不明智的,在有图片的下拉加载里,最好 加配个懒加载
2、真正的页面底部时才进行加载和渲染
==》用户较长时间等待
解决思路:
设置一个合理阈值,在用户滚动到页面底部之前,先进行提前加载
3、页面滚动事件
是否必须,还有出路吗 (因为监听是耗能的
解决思路:
防抖
标志位
滚动的主动询问
(现代化:IntersectionObserver 这个放在wayx说
1)Throttle允许我们限制激活响应的数量。我们可以限制每秒回调的数量。反过来,也就是说在激活下一个回调之前要等待多少时间; (节流
2)Debounce意味着当事件发生时,我们不会立即激活回调。相反,我们等待一定的时间并检查相同的事件是否再次触发。如果是,我们重置定时器,并再次等待。如果在等待期间没有发生相同的事件,我们就立即激活回调。(弹簧
滚动的主动询问:
把滚动事件替换为一个带有计时器的滚动处理程序,每100毫秒进行简单检查,看这段时间内用户是否滚动过。如果没有,则什么都不做;如果有,就进行处理。
4、dom操作
针对这部分的优化:dom缓存
超前阈值的懒加载+DOM Cache和图片Cache+滚动throttle模拟+CSS fadeIn
<div class="exp-list-box" id="expListBox">
<ul class="exp-list" id="expList">
{
list.map(item =>(
<div class="slide">
<li>
<a href={item.href}>
<img class="img" src="default.png" data-src={item.src}/>
<strong></strong>
<span class="writer">{item.writer}</span>
<span class="good-num">{item.num}</span>
</a>
</li>
</div>
))
}
</ul>
<div class="ui-refresh-down"></div>
</div>
请求返回的数据dataList可以理解为由9个对象构成的数组,也就是说,每次请求加载9个block-item。
.slide .img{
display: inline-block;
width: 90px;
height: 90px;
margin: 0 auto;
opacity: 0;
-webkit-transition: opacity 0.25s ease-in-out;
-moz-transition: opacity 0.25s ease-in-out;
-o-transition: opacity 0.25s ease-in-out;
transition: opacity 0.25s ease-in-out;
}
image的opacity设置为0,图片将会在成功请求并渲染后调整为1,辅助transition属性实现一个fade in效果(用户体验)
IntersectionObserver
vue-lazyload
https://juejin.im/post/59bf501ff265da06602971b9
其他
1、用户体验:
在图像加载完成时,使用淡入(fade in)效果出现。这在实际情况上会稍微慢一下,应该慢一个过渡执行时间。但用户体验上感觉会更快。这是已经被证实且普遍应用的小“trick”。