详解纯JavaScript+CSS怎样做页面滚动的动画
Admin 2021-10-21 群英技术资讯 501 次浏览
本文给大家分享用纯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>
先来一个简单的淡入动画效果:
.js-scroll { opacity: 0; transition: opacity 500ms; } .js-scroll.scrolled { opacity: 1; }
页面上的所有 js-scroll 元素都会被隐藏,不透明度为 0。当滚动到该元素区域时,给它加上 .scrolled 类名让它显现出来。
有了布局和样式,现在我们需要编写一个 JavaScript 函数,当元素滚动到视图中时,为它们分配类名。
我们来简单分解一下逻辑:
获取页面上所有 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; } .scrolled.fade-in-bottom { animation: fade-in-bottom 1s ease-in-out both; } .scrolled.slide-left { animation: slide-in-left 1s ease-in-out both; } .scrolled.slide-right { animation: slide-in-right 1s ease-in-out both; } @keyframes slide-in-left { 0% { transform: translateX(-100px); opacity: 0; } 100% { transform: translateX(0); opacity: 1; } } @keyframes slide-in-right { 0% { transform: translateX(100px); opacity: 0; } 100% { transform: translateX(0); opacity: 1; } } @keyframes fade-in-bottom { 0% { transform: translateY(50px); opacity: 0; } 100% { transform: translateY(0); opacity: 1; } } @keyframes fade-in { 0% { opacity: 0; } 100% { opacity: 1; } }
虽然加了不同动画元素,但我们不需要修改 JavaScript 代码,因为逻辑保持不变。这意味着我们可以在页面添加任何数量的不同动画,而无需编写新的函数。
每当我们在滚动监听器中绑定一个函数时,每次用户滚动页面,该函数都会被调用。滚动一个 500px 的页面会导致一个函数被调用至少 50 次。如果我们试图在页面上包含很多元素,这会导致我们的页面速度明显变慢。
我们可以通过使用“节流函数(Throttle Function)”来减少函数的调用次数。节流函数是一个高阶函数,它在指定的时间间隔内只调用传入的函数一次。
它对于滚动事件特别有用,因为我们不需要检测用户滚动的每个像素。例如,如果我们有一个定时器为 100ms 的节流函数,那么用户每滚动 100ms,该函数将只被调用一次。
节流函数在 JavaScript 中可以这样实现:
let throttleTimer = false const throttle = (callback, time) => { if (throttleTimer) return // 这里标记一下,以使函数不会重复执行 throttleTimer = true setTimeout(() => { // 到了指定的时间,调用传入的回调函数 callback() throttleTimer = false }, time) }
然后我们可以修改 window 对象上的 scroll 事件监听:
window.addEventListener('scroll', () => { throttle(handleScrollAnimation, 250) })
现在我们的 handleScrollAnimation 函数在用户滚动时每隔 250ms 就会被调用一次:
关于用纯JavaScript+CSS怎样做页面滚动动画的内容就介绍到这,感兴趣的朋友可以参考,希望能对大家有帮助,想要了解更多,大家可以关注其它的相关文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
本文实例为大家分享了js实现简单滑动解锁功能以及滑动拼图解锁的具体代码,供大家参考,具体内容如下简单实现滑动解锁,效果图是这样的
这篇文章主要介绍了如何在React中直接使用Redux,目前redux在react中使用是最多的,所以我们需要将之前编写的redux代码,融入到react当中去,本文给大家详细讲解,需要的朋友可以参考下
这篇文章给大家分享的是微信小程序点赞功能的实现。小编觉得挺有趣的,而且也很实用,因此分享给大家做个参考,文中示例代码介绍的非常详细,感兴趣的朋友接下来一起跟随小编看看吧。
本篇文章给大家带来了关于JavaScript的相关知识,reduce是数组原型对象上的一个方法,可以帮助我们操作数组。本文将和大家分享4个关于JavaScript中数组reduce的用法,希望对大家有所帮助。
我们在做分享页面的时候,会需要使用到vue浏览器返回监听,这样可以实现用户分享完页面之后,回退按钮返回到首页功能,达到实现增加访问量的目的。但是vue浏览器返回监听具体要怎么做呢?下面我们一起来了解一下实现步骤。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008