vue无限加载
template:
<template>
<div v-scroll="loadMore">
<ul class="news">
<li class="news__item" v-for="(news, index) in newslist">
{{index}}-{{news.title}}
</li>
</ul>
</div>
</template>
js:
<script>
export default{
data(){
return{
newslist: [
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'},
{title: 'hello world'}
]
}
},
methods: {
loadMore() {
let newAry = [];
for(let i = 0; i < 10; i++) {
newAry.push({title: 'hello world'})
}
this.newslist=this.newslist.concat(newAry);
}
},
directives: {
scroll: {
bind: function (el, binding){
window.addEventListener('scroll', ()=> {
if(document.documentElement.scrollTop + window.innerHeight >= el.clientHeight) {
console.log('scrollTop:'+document.documentElement.scrollTop+',innerHeight'+window.innerHeight+',clientHeight'+el.clientHeight);
let fnc = binding.value;
fnc();
}
})
}
}
}
}
</script>
css:
<style>
.news__item {
height: 80px;
border: 1px solid #ccc;
margin-bottom: 20px;
}
</style>
js无限加载
先了解三个变量:
- document.documentElement.scrollTop 滚动条滚动的距离
- window.innerHeight 浏览器窗口高度
- document.body.clientHeight 内容高度
html:
<body>
<div class="container">
<ul class="news" id="news">
<li class="news__item">1、hello world</li>
<li class="news__item">2、hello world</li>
<li class="news__item">3、hello world</li>
<li class="news__item">4、hello world</li>
<li class="news__item">5、hello world</li>
<li class="news__item">6、hello world</li>
<li class="news__item">7、hello world</li>
<li class="news__item">8、hello world</li>
<li class="news__item">9、hello world</li>
<li class="news__item">10、hello world</li>
</ul>
</div>
</body>
js:
<script>
var scrollDisable = false;
window.addEventListener('scroll', function() {
var scrollTop = document.documentElement.scrollTop;
if(scrollTop + window.innerHeight >= document.body.clientHeight) {
// if(!scrollDisable){
// 触发加载数据
loadMore();
console.log('scrollTop:'+scrollTop+',innerHeight:'+window.innerHeight+',clientHeight:'+document.body.clientHeight);
// }
}
});
// 表示列表的序号
var index = 10;
function loadMore() {
// 开始加载数据,就不能再次触发这个函数了
scrollDisable = true;
var content = '';
for(var i=0; i< 10; i++) {
content += '<li class="news__item">'+(++index)+'、hello world</li>'
}
var node = document.getElementById('news');
// 向节点内插入新生成的数据
var oldContent = node.innerHTML;
node.innerHTML = oldContent+content;
}
</script>
优化:
上面的例子并没有真正从接口获取数据,所以存在一个隐藏的 bug:当接口响应很慢的情况,滚动到底部正在加载数据时,稍微滚动一下仍会触发获取数据函数,这会造成同时请求多次接口,一次性返回大量数据。
解决办法是添加一个全局变量 scrollDisable,当第一次触发加载数据函数时,将该值设置为 true,根据该值判断是否要执行加载函数。
css:
<style>
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
li, ul {
list-style: none;
}
.container {
width: 980px;
margin: 0 auto;
}
.news__item {
height: 80px;
margin-bottom: 20px;
border: 1px solid #eee;
}
</style>