<template>
<div id="app">
<ul ref="list">
<li
v-for="({ elRef, isVisible }, idx) in items"
:ref="elRef"
:class="{ visible: isVisible.value }"
>
item {{ idx }} {{ isVisible }}
</li>
</ul>
</div>
</template>
<script setup>
import { ref, unref, onMounted } from "vue";
const list = ref(null);
const items = Array.from({ length: 42 }, () => ({
elRef: ref(null),
isVisible: ref(true)
}));
onMounted(() => {
const refsMap = new WeakMap();
const onObserve = (entries, observer) => {
for (const entrie of entries) {
const { isIntersecting, target } = entrie;
const { isVisible } = refsMap.get(target);
isVisible.value = isIntersecting;
}
};
const observer = new IntersectionObserver(onObserve, {
root: list.value,
threshold: 1.0
});
items.forEach((it) => {
refsMap.set(it.elRef.value, it);
observer.observe(it.elRef.value);
});
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
color: #2c3e50;
}
ul {
display: flex;
list-style: none;
padding: 0;
margin: 0;
overflow: auto;
}
li {
flex: 0 0;
padding: 15px;
margin: 5px;
background-color: #ccc;
text-align: center;
transition: background-color 300ms;
}
li.visible {
background-color: forestgreen;
}
</style>
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.