console
let listData = []
for (let i = 0; i < 10; i ++) {
listData.push({ value: i })
}
new Vue({
computed: {
listHeight() {
return this.listData.length * this.itemSize;
},
visibleCount() {
console.log(Math.ceil(this.screenHeight / this.itemSize))
return Math.ceil(this.screenHeight / this.itemSize)
},
getTransform() {
return `translate3d(0,${this.startOffset}px,0)`;
},
visibleData() {
return this.listData.slice(this.start, Math.min(this.end, this.listData.length));
}
},
mounted() {
this.screenHeight = this.$el.clientHeight
console.log(this.$el.clientHeight)
this.start = 0;
this.end = this.start + this.visibleCount;
},
data() {
return {
screenHeight: 0,
startOffset: 0,
start: 0,
end: null,
itemSize: 200,
listData: listData
};
},
methods: {
scrollEvent() {
let scrollTop = this.$refs.list.scrollTop;
this.start = Math.floor(scrollTop / this.itemSize);
this.end = this.start + this.visibleCount;
this.startOffset = scrollTop - (scrollTop % this.itemSize);
}
}
}).$mount("#app")
<div id="app">
<div ref="list" class="infinite-list-container" @scroll="scrollEvent($event)">
<div class="infinite-list-phantom" :style="{ height: listHeight + 'px' }"></div>
<div class="infinite-list" :style="{ transform: getTransform }">
<div ref="items"
class="infinite-list-item"
v-for="item in visibleData"
:key="item.id"
:style="{ height: itemSize + 'px',lineHeight: itemSize + 'px' }"
>{{ item.value }}</div>
</div>
</div>
</div>
html {
height: 100%;
}
body {
height: 100%;
margin: 0;
}
#app {
height: 100%;
}
.infinite-list-container {
overflow: auto;
position: relative;
-webkit-overflow-scrolling: touch;
}
.infinite-list-phantom {
position: absolute;
left: 0;
top: 0;
right: 0;
z-index: -1;
}
.infinite-list {
left: 0;
right: 0;
top: 0;
position: absolute;
}
.infinite-list-item {
padding: 5px;
color: #555;
box-sizing: border-box;
border-bottom: 1px solid #999;
height:200px;
}