Vue技巧 | 在Vue3中使元素在滚动视图时淡入

3,422 阅读5分钟

除了视差组件和滚动事件外,添加响应式触摸的一种好方法是使元素在滚动视图时淡入。

在本技巧中,将介绍如何使用滚动事件和CSS转换在Vue3中实现此功能。

这是我们将学习如何在本教程中进行构建的屏幕截图。


Vue3相关文章:


样式化我们的fadin元素

我们要做的第一件事是构建模板并设置组件样式。在此示例中,我们将使用空白块来说明事情如何进行。

因此,在我们的模板中,我们只想...

  • 包装容器 container
  • 一些full-width元素
  • 一些half-width元素添加一些变化
<template>
  <div class='container'>
    <div class='fade-in full-width' />
    <div class='fade-in full-width' />
    <div class='half-width fade-in' />
    <div class='half-width fade-in' />
  </div>
</template>

然后,要对它们进行样式设置,我们要构建一个基本的容器,然后使用一些填充,颜色和适当的宽度来对我们的块进行样式设置。

<style scoped>
  .container {
    width: 80%;
    min-width: 450px;
    margin: 0 auto;
  }

  .fade-in {
    background-color: #2ecc71;
    height: 500px;
    margin-bottom: 50px;
    opacity: 0;
    transition: 0.3s all ease-out;
    transform: scale(0.8);
    box-sizing: border-box;
    padding: 20px;
    display: inline-block;
  }
  .full-width{
    width: 100%;
  }

  .half-width {
    width: 47.5%;
  }

  .half-width:nth-of-type(2n + 1) {
    margin-right: 2.5%;
  }

  .half-width:nth-of-type(2n) {
    margin-left: 2.5%;
  }
</style>

需要注意的一件事是,我们所有的淡入元素均以默认不透明度0开始,我们将使用脚本来处理它们,我们还将改变元素的比例。

事实上,我们的淡入元素被赋予了一个过渡属性,这意味着当我们改变不透明度和比例时,它将在我们的两个值之间平滑地过渡——给我们想要的平滑效果。

所以,如果我们加载我们的页面,我们不应该看到任何东西——但我们应该能够向下滚动我们的页面,因为我们的元素就在那里,只是完全透明。

让我们使用一些Javascript使其可见。

使我们的元素淡入

在本教程中,我们将使用Vue3 Composition API——因此,在脚本中,我们首先要创建 setup 方法并导入一些生命周期hooks。

<script>
import { onMounted, onUnmounted } from 'vue'
export default {
  setup () {

    onMounted(() => {

    })

    onUnmounted(() => {

    })
  }
}
</script>

然后,我们创建一个包含所有淡入元素的数组。我们可以使用 document.getElementsByClassName 进行此操作-但是,这将返回 HTMLCollection,并且我们需要一个数组,因此我们可以使用Javascript的 Array.from 方法进行强制转换。

onMounted(() => {
  fadeInElements = Array.from(document.getElementsByClassName('fade-in'))
})

现在我们有了一个要淡入的所有元素的数组,我们想要做一些事情:

  1. 每当视图被滚动时,就会在它们上面迭代。
  2. 确定元素是否可见。
  3. 如果是的话,将其淡入并从数组中删除

首先,我们要在安装(mounted)组件时创建滚动侦听器,并在卸载(unmounted)组件时将其删除。我们要做的另一件事是,在安装组件时调用 handleScroll 方法,以便加载某些内容,而无需用户滚动查看内容。

var fadeInElements = []

onMounted(() => {
  fadeInElements = Array.from(document.getElementsByClassName('fade-in'))
  document.addEventListener('scroll', handleScroll)
  handleScroll()
})

onUnmounted(() => {
  document.removeEventListener('scroll', handleScroll)
})

在滚动侦听器中,让我们创建一个 for 循环,用于遍历我们创建的淡入元素数组。

const handleScroll = (evt) => {
  for (var i = 0; i < fadeInElements.length; i++) {
    var elem = fadeInElements[i]
  }
}

此时,我们需要某种辅助方法来确定元素是否可见。为此,我们将使用元素的bounding rectangle 返回元素相对于视口的大小和位置。

我们还要添加一个小的缓冲区,所以在淡入之前,至少有 200px 的元素必须是可见的。这将真正增强效果,因为它可以确保网站访问者能看到正在发生的事情。如果没有这个缓冲区,我们的淡入过渡会在我们元素的1个像素出现在屏幕上时触发,而大部分的元素会在视口之外。

const isElemVisible = (el) => {
  var rect = el.getBoundingClientRect()
  var elemTop = rect.top + 200 // 200 = buffer
  var elemBottom = rect.bottom
  return elemTop < window.innerHeight && elemBottom >= 0
}

回到滚动事件侦听器内部,我们想了解每个元素的 isElemVisible 帮助法是否为 true。如果是这样,我们要更改元素的不透明度和比例,然后将其从数组中删除。

for (var i = 0; i < fadeInElements.length; i++) {
  var elem = fadeInElements[i]
  if (isElemVisible(elem)) {
    elem.style.opacity = '1'
    elem.style.transform = 'scale(1)'
    fadeInElements.splice(i, 1) // 只让它运行一次
  }
}

现在,如果我们回到我们的应用程序中去检查一下,你会发现,当我们滚动时,元素会变得清晰可见。这正是我们想要的!

如果你愿意,我们就完成了!

于是,我们就有了我们一直在寻找的淡入滚动效果!有很多方法可以扩展这个效果,比如说。

  • 滚动时使元素淡出,以便可以再次淡入。
  • 使用CSS动画代替过渡,增加更多的高级动画。
  • 将逻辑提取到自定义指令中,以便可以在整个项目中重复使用。

只要你掌握了滚动侦听器CSS animations/transitions 的窍门,那么你就能做到无懈可击。

我希望你学到了一两件事,并且可以想到一些很酷的方法来将其中一些技术添加到自己的Vue项目中。


来源:itnext.io,作者:Matt Maribojoc,翻译:公众号《前端全栈开发者》