加入收藏 | 设为首页 | 会员中心 | 我要投稿 91站长网 (https://www.91zhanzhang.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

详解纯JavaScript+CSS怎样做页面滚动的动画

发布时间:2022-01-11 16:41:54 所属栏目:语言 来源:互联网
导读:本文给大家分享用纯JavaScript+CSS怎样做页面滚动的动画的内容,让元素根据滚动位置实现动画效果比较流行,除了本文的方法也可以用第第三方插件或库来实现,废话不多说,下面直接看代码。 先预览一下实现的效果: 我们使用 CSS 来实现动画,用 JavaScript 来
       本文给大家分享用纯JavaScript+CSS怎样做页面滚动的动画的内容,让元素根据滚动位置实现动画效果比较流行,除了本文的方法也可以用第第三方插件或库来实现,废话不多说,下面直接看代码。
 
先预览一下实现的效果:
 
 
 
       我们使用 CSS 来实现动画,用 JavaScript 来处理触发所需的样式。我们先来创建布局。
 
创建布局
我们先使用 HTML 创建页面布局,然后为需要实现动画的元素分配一个通用类名,后面的 JavaScript 通过此类名定位这些元素。这里我们给需要根据滚动实现动画的元素指定为类名 js-scroll,HTML 代码如下:
 
<section class="scroll-container">
  <div class="scroll-element js-scroll"></div>
  <div class="scroll-caption">This animation fades in from the top.</div>
</section>
添加 CSS 样式
先来一个简单的淡入动画效果:
 
.js-scroll {
  opacity: 0;
  transition: opacity 500ms;
}
 
.js-scroll.scrolled {
  opacity: 1;
}
页面上的所有 js-scroll 元素都会被隐藏,不透明度为 0。当滚动到该元素区域时,给它加上 .scrolled 类名让它显现出来。
 
用 JavaScript 操作元素
有了布局和样式,现在我们需要编写一个 JavaScript 函数,当元素滚动到视图中时,为它们分配类名。
 
我们来简单分解一下逻辑:
 
获取页面上所有 js-scroll 元素
使这些元素默认淡出不可见
检测元素是否在视窗内
如果元素在视窗内则分配 scrolled 类名
获取目标元素
获取页面上所有 js-scroll 元素,使用 document.querySelectorAll() 即可:
 
const scrollElements = document.querySelectorAll('.js-scroll')
默认淡出所有目标元素
遍历这些元素,使其全部淡出不可见:
 
scrollElements.forEach((el) => {
  el.style.opacity = 0
})
检测元素是否在视窗内
我们可以通过判断元素距离页面顶部的间距是否小于页面可见部分的高度,来检测元素是否在用户视窗中。
 
在 JavaScript 中,我们使用 getBoundingClientRect().top 方法来获取元素与页面顶部的距离,使用 window.innerHeight 或 document.documentElement.clientHeight 来获取视窗的高度。
 
 
 
我们将使用上述逻辑创建一个 elementInView 函数:
 
const elementInView = (el) => {
  const elementTop = el.getBoundingClientRect().top
 
  return (
    elementTop <= (window.innerHeight || document.documentElement.clientHeight)
  )
}
我们可以修改这个函数来检测元素是否向页面滚动了 x 个像素,或者检测页面滚动的百分比。
 
const elementInView = (el, scrollOffset = 0) => {
  const elementTop = el.getBoundingClientRect().top
 
  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) - scrollOffset
  )
}
在这种情况下,如果元素已经按 scrollOffset 的数量滚动到页面中,该函数返回 true。我们再稍作修改,把参数 scrollOffset 变成百分比:
 
const elementInView = (el, percentageScroll = 100) => {
  const elementTop = el.getBoundingClientRect().top
 
  return (
    elementTop <=
    (window.innerHeight || document.documentElement.clientHeight) *
      (percentageScroll / 100)
  )
}
这部分可以根据自己的特定需求来定义逻辑。
 
注意:可以使用 Intersection Observer API[2] 来实现同样的效果,但它不支持 IE。
 
给元素添加类名
现在我们已经能够检测到元素是否已经滚动到页面中,我们需要定义一个函数来处理该元素的显示--本例中我们通过分配 scrolled 类名来显示该元素。
 
const displayScrollElement = (element) => {
  element.classList.add('scrolled')
}
然后,再把我们前面的逻辑与 displayScrollElement 函数结合起来,并使用 forEach 方法在所有 js-scroll 元素上调用该函数。
 
const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el)
    }
  })
}
另外,当元素不再在视图中时,需要将其重置为默认状态,我们可以通过定义一个 hideScrollElement 来实现:
 
const hideScrollElement = (element) => {
  element.classList.remove("scrolled");
};
 
const handleScrollAnimation = () => {
  scrollElements.forEach((el) => {
    if (elementInView(el, 100)) {
      displayScrollElement(el);
    } else {
      hideScrollElement(el);
    }
  }
最后,我们将把上面的方法传递到窗口的滚动事件监听中,这样每当用户滚动时它就会运行。
 
window.addEventListener('scroll', () => {
  handleScrollAnimation()
})
我们已经实现了滚动动画的所有功能。
 
完善示例
请大家回到文章开头看看效果图。看到,这些元素以不同的动画出现。这是通过给类名分配不同的 CSS 动画来实现的。这个示例的 HTML 是这样的:
 
<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in"></div>
  <div class="scroll-caption">淡入动效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll fade-in-bottom"></div>
  <div class="scroll-caption">切入顶部动效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-left"></div>
  <div class="scroll-caption">从左边切入动效</div>
</section>
<section class="scroll-container">
  <div class="scroll-element js-scroll slide-right"></div>
  <div class="scroll-caption">从右边切入动效</div>
</section>
这里我们给不同动效的元素分配了不同的 CSS 类名,下面是这些类对应的 CSS 代码:
 
.scrolled.fade-in {
  animation: fade-in 1s ease-in-out both;
}

(编辑:91站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读