在做前端 UI 效果时,让元素根据滚动位置实现动画效果是一个非常流行的设计,通常我们会使用第三方插件或库来实现。在本教程中,我将教大家使用纯 JavaScript 和 CSS 来实现。

先预览一下实现的效果:

我们使用 CSS 来实现动画,用 JavaScript 来处理触发所需的样式。我们先来创建布局。

创建布局

我们先使用 HTML 创建页面布局,然后为需要实现动画的元素分配一个通用类名,后面的 JavaScript 通过此类名定位这些元素。这里我们给需要根据滚动实现动画的元素指定为类名 js-scroll,HTML 代码如下:

This animation fades in from the top.

添加 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 是这样的:

淡入动效
切入顶部动效
从左边切入动效
从右边切入动效

这里我们给不同动效的元素分配了不同的 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 实现页面滚动动画的详细内容,更多关于JavaScript 页面滚动的资料请关注脚本之家其它相关文章!

html如何设置滚动动画,JavaScript 实现页面滚动动画相关推荐

  1. JavaScript实现页面滚动到div区域div以动画方式出现

    用JavaScript实现页面滚动效果,以及用wow.js二种方式实现网页滚动效果 要实现效果是页面滚动到一块区域,该区域以动画方式出现. 这个效果需要二点: 一:我们要先写好一个css动画. 二:用 ...

  2. 监听某个区域滚动_监听页面滚动及滚动到指定位置

    一.原生js通过window.onscroll监听 window.onscroll = function() { //为了保证兼容性,这里取两个值,哪个有值取哪一个 //scrollTop就是触发滚轮 ...

  3. JavaScript 实现页面滚动动画

    先预览一下实现效果: 我们使用 CSS 来实现动画,用 JavaScript 来处理触发所需的样式.我们先来创建布局. 创建布局 我们先使用 HTML 创建页面布局,然后为需要实现动画的元素分配一个通 ...

  4. js页面滚动,设置锚点,控制页面滚动到某个节点位置

    1.获取某Dom元素距离可视窗口顶部的距离 元素在网页里的坐标-页面滚动的距离 获取元素距离可视窗口顶部的距离 = dom.ofisetTop - window.pageYOffset; 元素自身的高 ...

  5. Java写字幕滚动,使用JavaScript实现连续滚动字幕效果的方法

    我们一般都用Marquee标签控制元素的滚动.但是单向的Marquee滚动是不连续的,每滚完一幕,就会出现一次空白.而下面介绍中的滚动则是连续的,毫不间断. 下面为你介绍这是如何实现的. 为了滚动能够 ...

  6. 滚动旋钮时禁止页面滚动-jquery.knob.js

    jquery.knob.js一款很棒的jquery旋钮插件 gayhub地址:https://github.com/aterrien/jQuery-Knob 当鼠标滚轮作用于旋钮时,禁止页面滚动 $( ...

  7. JavaScript实现 页面滚动图片加载

    原理: 1.给页面绑定滚动事件: 2.加载页面的时候把真正的图片地址放在某属性中: 3.然后再滚动过程中判断元素是否进入当前浏览器窗口内: 4.最后加载图片,当然加载什么,用什哪种用户体验都得由你决定 ...

  8. javaScript:获取页面滚动距离的元素.scrollTop和元素.scrollLeft获取的兼容性处理(IE、Chrome 、 FireFox、Safari)

    + 向上滚动的距离: 元素.scrollTop 区别: ==> IE 浏览器 + 没有 DOCTYPE 声明的时候,用这两个都行 + 有 DOCTYPE 声明的时候,只能用 document.d ...

  9. css如何让滚轮滚动时 不让页面滚动_中国第五届 CSS 大会参会总结

    编者按:本文作者:安佳,360 搜索事业部的前端开发工程师,W3C CSS 工作组成员. 本次大会共有 7 个主题: 新时代 CSS 布局.陈慧晶 剖析 css-tricks 新版,为你所用.大漠 C ...

最新文章

  1. 【廖雪峰python入门笔记】list_倒序访问
  2. android 安装sqlite3,Android真机安装sqlite3的方法
  3. linux下如何查看程序写入内存数据_linux到底如何正确关机
  4. 第三期CSIG图像图形学科前沿讲习班-详细日程
  5. OpenCASCADE绘制测试线束:OCAF 命令之数据框架命令
  6. 为 Angular service 注册 provider 的三种方式
  7. chrome console js多行输入
  8. python用xpath爬取10页网站图片
  9. (78)Vivado设置时钟组约束
  10. mysql数据库实现修改密码代码_MySQL数据库的更改密码(附源代码)
  11. 242.有效的字母异位词(力扣leetcode) 博主可答疑该问题
  12. 局部路径规划中的人工势场法
  13. html设置自动居中显示,css+div实现整个html居中最简单方法
  14. 基于证据理论的多源数据融合仿真实验matlab代码
  15. 教你如何做好移动支付行业
  16. 牛人在chinaren上的经典歌曲集
  17. LruCache缓存图片+清除本地缓存
  18. 微信头像失效_微信公众号头像链接判断是否有效
  19. ps导出gif时是html,ps导出gif图步骤图解
  20. 芝麻信用免押降低消费门槛 今年过年“以租代买”成潮流

热门文章

  1. Android传感器编程入门
  2. Swift傻傻分不清楚系列(六)集合类型
  3. MySQL触发器(转载)
  4. web安全学习-验证机制存在的问题
  5. Java this 关键字的用法
  6. 20145212 《信息安全系统设计基础》第2周学习总结
  7. 动态代理之Cglib浅析
  8. 【GOF23设计模式】原型模式
  9. Windows 10 Threshold 2 升级记录
  10. C#-面向对象的多态思想 ---ShinePans