在vue3,nuxt3环境下,我有一个v-for循环出来的数组,我希望添加一些动画。并且用IntersectionObserver和css实现。例如这个数组是四个div,每个大的div里面有两个小的div。我的第一个大的div里左边是图片,右边是文字。第二个是左边是文字,右边是图片,以此类推。当我滚动到第一个大的div时,左边的图片上会出现一个div,div里面是一些文字。右边的div里面的文字会渐渐的由下而上出现。滚动到第二个大的div的时候,右边的图片上会出现文字,左边的文字会由下而上出现。当我滚动的时候,发现两个div都出现在了可见区域内,那么我们需要显示可见区域最高(也就是top值最高)的那个div,也就是图片上的文字会出现
时间: 2024-03-15 18:47:25 浏览: 229
在这种情况下,你需要使用 IntersectionObserver 和一些 JavaScript 代码来计算可见区域内元素的位置,然后根据它们的位置来决定哪个元素应该显示在最上面。具体实现步骤如下:
1. 在父元素中为每个大的 div 添加一个 IntersectionObserver,用于检测该元素是否在用户的视窗中。然后,在 IntersectionObserver 的回调函数中,记录每个元素的位置信息(例如,每个元素的 top 值)。
```
<template>
<div class="wrapper" ref="wrapper">
<div class="item" v-for="(item, index) in items" :key="index" ref="item">
<div class="left" :class="{ 'is-visible': isVisible[index].isLeftVisible }">
<img src="...">
<div class="text">
...
</div>
</div>
<div class="right" :class="{ 'is-visible': isVisible[index].isRightVisible }">
<div class="text">
...
</div>
<img src="...">
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [...],
isVisible: []
}
},
mounted() {
const options = {
root: null,
rootMargin: '0px',
threshold: 0.5
}
const observer = new IntersectionObserver(this.handleIntersection, options)
this.$refs.item.forEach(item => observer.observe(item))
},
methods: {
handleIntersection(entries) {
entries.forEach(entry => {
const index = this.$refs.item.indexOf(entry.target)
const visibleRect = entry.intersectionRect
const itemRect = entry.boundingClientRect
const wrapperRect = this.$refs.wrapper.getBoundingClientRect()
const isVisible = {
isLeftVisible: false,
isRightVisible: false
}
if (itemRect.top >= wrapperRect.top && itemRect.bottom <= wrapperRect.bottom) {
isVisible.isLeftVisible = true
isVisible.isRightVisible = true
} else {
const leftTop = itemRect.top - wrapperRect.top
const leftBottom = itemRect.bottom - wrapperRect.top
const rightTop = itemRect.top - wrapperRect.top
const rightBottom = itemRect.bottom - wrapperRect.top
if (visibleRect.top <= leftTop && visibleRect.bottom >= leftBottom) {
isVisible.isLeftVisible = true
}
if (visibleRect.top <= rightTop && visibleRect.bottom >= rightBottom) {
isVisible.isRightVisible = true
}
}
this.isVisible[index] = isVisible
})
}
}
}
</script>
```
2. 在 CSS 中定义动画效果,例如:
```
.item {
opacity: 0;
transition: opacity 0.5s ease;
}
.is-visible {
opacity: 1;
}
.left .text {
transform: translateY(100%);
transition: transform 0.5s ease;
}
.left.is-visible .text {
transform: translateY(0);
}
.right .text {
transform: translateY(100%);
transition: transform 0.5s ease;
}
.right.is-visible .text {
transform: translateY(0);
}
```
3. 在 JavaScript 中计算每个元素的位置信息。首先,你需要获取可见区域的位置信息,然后计算每个元素相对于可见区域的位置信息(例如,每个元素的 top 值)。根据这些位置信息,你可以判断哪个元素应该显示在最上面。
4. 当两个 div 重叠时,你可以使用 z-index 属性来控制它们的显示顺序,确保可见度最高的 div 显示在最上面。例如:
```
.wrapper {
position: relative;
}
.item {
position: relative;
z-index: 1;
}
.left.is-visible {
z-index: 2;
}
.right.is-visible {
z-index: 3;
}
```
这样,当你滚动到不同的大的 div 时,左边或右边的 div 会显示动画效果,并确保可见度最高的元素显示在最上面。
阅读全文