console
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://unpkg.com/vue@3.2.27/dist/vue.global.js">
</script>
<title>VirtualScroll</title>
</head>
<body>
<div id="app">
<div ref="demo" class="scroll-box demo" :style="`height: ${showNumber * itemHeight}px;`">
<div class="scroll-blank" :style="`height: ${data.length * itemHeight}px;`"></div>
<div class="scroll-data" :style="`top: ${positionTop}px;`">
<div v-for="(item, index) in activeList" :key="item" class="scroll-item">
{{ item }}
</div>
</div>
</div>
</div>
<script>
const { computed, onMounted, onUnmounted, ref } = Vue
const createData = (length) => {
return Object.keys(new Array(length).fill(''))
}
const App = {
setup() {
const demo = ref(null)
const showNumber = 20
const itemHeight = 20
const data = createData(1000)
let startNum = ref(0)
let positionTop = ref(0)
const activeList = computed(() => {
const start = startNum.value
return data.slice(start, start + showNumber)
})
const scrollEvent = (event) => {
const { scrollTop } = event.target
startNum.value = parseInt(scrollTop / itemHeight)
positionTop.value = scrollTop
console.log('-----------');
}
onMounted(() => {
demo.value.addEventListener('scroll', throttle(scrollEvent, 100))
})
onUnmounted(() => {
if (!demo.value) return
demo.value.removeEventListener('scroll', scrollEvent)
demo.value = null
})
function throttle(fn, delay) {
let timer = null;
let startTime = Date.now();
return function () {
const currentTime = Date.now();
const remaining = delay - (currentTime - startTime);
const context = this;
const args = arguments;
clearTimeout(timer);
if (remaining <= 0) {
fn.apply(context, args);
startTime = Date.now();
} else {
timer = setTimeout(fn, remaining);
}
}
}
return {
showNumber,
itemHeight,
demo,
positionTop,
data,
activeList,
}
},
}
const app = Vue.createApp(App)
app.mount('#app')
</script>
<style>
.scroll-box {
position: relative;
overflow: auto;
width: 400px;
border: 1px solid rgb(0, 0, 0);
}
.scroll-data {
position: absolute;
width: 100%;
}
.scroll-item {
height: 20px;
}
.scroll-item:hover {
background: rgb(104, 111, 211);
color: #fff;
}
</style>
</body>
</html>