瀑布流改进-增加监听时间加载图片保证渲染时能获取正确的元素高度 #
当瀑布流中的元素包含图片并且尺寸不明确的时候(更佳的做法是在图片文件中包含图片尺寸信息,来提升前端的渲染体验),监听每一次图片加载的load状态,当图片loaded,则进行获取高度插入下一组瀑布流数据。
在上次基础上进行一些改动,下面是代码,还增加了reduce的生成器,用于处理移除瀑布流数据的情况。
实例效果预览图 #
Template and CSS #
<div class="content">
<div class="list" ref="l1">
<TransitionGroup name="add">
<div class="item" v-for="(i1, index1) in list1" :key="index1"><img :src="i1.img" ref="imgs">{{
i1.text }}</div>
</TransitionGroup>
</div>
<div class="list" ref="l2">
<TransitionGroup name="add">
<div class="item" v-for="(i2, index2) in list2" :key="index2"><img :src="i2.img" ref="imgs">{{ i2.text }}</div>
</TransitionGroup>
</div>
</div>
Script #
import { onMounted, ref, watch } from 'vue';
interface Data {
text: string,
img?: string,
}
const data = ref<Data[]>([
{ text: '图文一', img: 'https://live.mdnplay.dev/zh-CN/docs/Web/HTML/Element/img/favicon144.png' },
{ text: '图文二图文二' ,img: 'https://live.mdnplay.dev/zh-CN/docs/Web/HTML/Element/img/clock-demo-400px.png'},
{ text: '图文三图文三图文三' ,img: 'https://interactive-examples.mdn.mozilla.net/media/cc0-images/grapefruit-slice-332-332.jpg'},
{ text: '图文四图文四图文四图文四' ,img: 'https://interactive-examples.mdn.mozilla.net/media/examples/balloon-small.jpg'},
{ text: '图文五图文五图文五图文五图文五' ,img: ''}
])
const imgs = ref([])
const i = ref(0)
const list1 = ref<Data[]>([])
const list2 = ref<Data[]>([])
const l1 = ref()
const l2 = ref()
function* addData() {
if (i.value != data.value.length) {
if (l1.value.offsetHeight <= l2.value.offsetHeight) {
yield list1.value.push(data.value[i.value++])
} else {
yield list2.value.push(data.value[i.value++])
}
}
}
function* reduceData() {
if (i.value != -1) {
if (l1.value.offsetHeight > l2.value.offsetHeight) {
i.value--
yield list1.value.splice(list1.value.length - 1, 1)
} else {
i.value--
yield list2.value.splice(list2.value.length - 1, 1)
}
}
}
watch(i, (newV, oldV) => {
console.log(l1.value.offsetHeight, l2.value.offsetHeight)
if (newV > oldV) {
setTimeout(() => {
console.log(imgs.value)
imgs.value[imgs.value.length-1].addEventListener("load", () => {
console.log('loaded')
addData().next()
});
}, 120);
} else {
setTimeout(() => {
reduceData().next()
}, 200);
}
})
onMounted(() => {
addData().next()
})