为了实现“原生js实现页面滚动动画”,我们需要以下步骤:
为了实现“原生js实现页面滚动动画”,我们需要以下步骤:
1. 监听页面滚动事件
在监听“页面滚动事件”之前,需要先获得“滚动高度”和“窗口可视高度”两个常量,以便后续的计算。这里的计算方法如下:
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;   // 获取滚动高度
const windowHeight = window.innerHeight || document.documentElement.clientHeight;  // 获取窗口可视高度
在获得这两个常量之后,我们可以使用addEventListener()方法监听“页面滚动事件”,其中scroll事件就是滚动事件。
document.addEventListener('scroll', () => {
  // 处理滚动事件
});
2. 实现滚动动画
在监听到“页面滚动事件”之后,就需要根据滚动高度来控制对应元素的样式(如transform、opacity等)以显示滚动动画。
实现滚动动画的方法有很多种,这里介绍两种常见的实现方式。
方式一:逐帧动画
逐帧动画是一种比较简单的动画方式,在该方式下,每一步都明确指定下一步的状态,以达到动画效果。大概的步骤如下:
- 获取需要操作的元素
- 计算元素应该处于的状态
- 使用requestAnimationFrame()函数监听浏览器的刷新频率,并以此更新元素的状态
下面是一段逐帧动画的示例代码:
// 获取需要操作的元素
const element = document.getElementById('target');
document.addEventListener('scroll', () => {
  // 计算元素应该处于的状态
  const targetOffsetTop = element.offsetTop;
  const targetOffsetBottom = targetOffsetTop + element.offsetHeight;
  const scrollBottom = scrollTop + windowHeight;
  if (scrollBottom > targetOffsetTop && scrollTop < targetOffsetBottom) {
    // 当元素进入可视区域内时,开始逐帧动画
    const start = performance.now();   // 记录开始时间
    const animate = timestamp => {
      const runtime = timestamp - start;   // 计算运行时长
      // 计算元素应该处于的状态
      const translateY = (1 - runtime / 1000) * 100;
      // 更新元素的状态
      element.style.transform = `translateY(-${translateY}px)`;
      if (runtime < 1000) {
        // 动画未结束时,递归调用requestAnimationFrame()函数
        requestAnimationFrame(animate);
      }
    };
    requestAnimationFrame(animate);
  } else {
    // 当元素离开可视区域时,恢复元素的原始状态
    element.style.transform = '';
  }
});
在以上代码中,我们首先使用getElementById()方法获取需要操作的元素,然后在监听到“页面滚动事件”时,计算出元素在当前状态下应该处于的位置,并使用requestAnimationFrame()函数来逐帧更新元素的状态。
逐帧动画的优点是实现简单,而且能够精确控制每一帧的状态。但是,需要注意的是,该方法的运行效率较低,在复杂的动画场景下可能出现卡顿现象。
方式二:CSS3动画
CSS3动画是一种比较流行的动画方式,通过CSS3中的transition和animation属性,可以轻松地实现各种复杂的动画效果,而且具有较高的运行效率。
下面是一段CSS3动画的示例代码:
// 获取需要操作的元素
const element = document.getElementById('target');
// 为元素添加动画属性
element.style.transition = 'transform 1s linear';
document.addEventListener('scroll', () => {
  // 计算元素应该处于的状态
  const targetOffsetTop = element.offsetTop;
  const targetOffsetBottom = targetOffsetTop + element.offsetHeight;
  const scrollBottom = scrollTop + windowHeight;
  if (scrollBottom > targetOffsetTop && scrollTop < targetOffsetBottom) {
    // 当元素进入可视区域内时,添加动画类名
    element.classList.add('animated');
  } else {
    // 当元素离开可视区域时,移除动画类名
    element.classList.remove('animated');
  }
});
在以上代码中,我们首先使用getElementById()方法获取需要操作的元素,然后为元素添加了一个CSS3动画属性,其中transition属性用于指定动画效果,其后的1s表示动画运行时长,linear表示动画运动的速度。
在监听到“页面滚动事件”时,计算出元素在当前状态下应该处于的位置,并根据结果给元素添加或移除相应的类名。
CSS3动画的优点是实现简单,而且具有较高的运行效率。缺点是相对于逐帧动画来说,有一定的限制,不太适用于一些较为复杂的动画场景。
示例
下面是两个基于上述方法实现的示例:
示例一:逐帧动画
该示例实现了一个“上滑显示”效果,即当页面滚动到某个元素时,该元素会从下方逐渐滑入屏幕。
<div class="box" id="target"></div>
.box {
  height: 100px;
  background-color: #f00;
  margin-top: 500px;
}
const element = document.getElementById('target');
document.addEventListener('scroll', () => {
  const targetOffsetTop = element.offsetTop;
  const targetOffsetBottom = targetOffsetTop + element.offsetHeight;
  const scrollBottom = scrollTop + windowHeight;
  if (scrollBottom > targetOffsetTop && scrollTop < targetOffsetBottom) {
    const start = performance.now();
    const animate = timestamp => {
      const runtime = timestamp - start;
      const translateY = (1 - runtime / 1000) * 100;
      element.style.transform = `translateY(-${translateY}px)`;
      if (runtime < 1000) {
        requestAnimationFrame(animate);
      }
    };
    requestAnimationFrame(animate);
  } else {
    element.style.transform = '';
  }
});
示例二:CSS3动画
该示例实现了一个“闪烁显示”效果,即当页面滚动到某个元素时,该元素会闪烁几下并再次消失。
<div class="box" id="target"></div>
.box {
  height: 100px;
  background-color: #f00;
  margin-top: 500px;
}
.box.animated {
  animation: blink 1s linear;
}
@keyframes blink {
  0% { opacity: 1; }
  50% { opacity: 0; }
  100% { opacity: 1; }
}
const element = document.getElementById('target');
document.addEventListener('scroll', () => {
  const targetOffsetTop = element.offsetTop;
  const targetOffsetBottom = targetOffsetTop + element.offsetHeight;
  const scrollBottom = scrollTop + windowHeight;
  if (scrollBottom > targetOffsetTop && scrollTop < targetOffsetBottom) {
    element.classList.add('animated');
    setTimeout(() => element.classList.remove('animated'), 1000);
  } else {
    element.classList.remove('animated');
  }
});
以上就是基于原生js实现页面滚动动画的完整攻略,其中涵盖了逐帧动画和CSS3动画两种实现方式,可以根据具体情况选择相应的方法以实现所需效果。
本文标题为:原生js实现页面滚动动画
 
				
         
 
            
        - 关于 vuejs2:\\”TypeError: Cannot read property \\ 2022-09-15
- Layui Table 的列隐藏问题 2023-09-13
- JavaScript事件类型中焦点、鼠标和滚轮事件详解 2023-11-30
- 通过CSS数学函数实现动画特效 2022-11-20
- SSH+Jquery+Ajax框架整合 2022-10-17
- Ajax实现局部刷新的方法实例 2023-02-23
- 3.实体标签.html 2023-10-27
- webpack学习笔记一:安装webpack、webpack-dev-server、内存加载js和html文件、loader处理非js文件 2023-10-28
- 【vue】class、style的用法 2023-10-08
- 第12天:校验及常见错误 2022-11-04
 
						 
						 
						 
						 
						 
				 
				 
				 
				