广告
返回顶部
首页 > 资讯 > 前端开发 > html >HTML5定时器requestAnimationFrame怎么用
  • 725
分享到

HTML5定时器requestAnimationFrame怎么用

2024-04-02 19:04:59 725人浏览 独家记忆
摘要

这篇文章主要介绍了HTML5定时器requestAnimationFrame怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言计时器一

这篇文章主要介绍了HTML5定时器requestAnimationFrame怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

前言

计时器一直是javascript动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,这样才能确保浏览器有能力渲染产生的变化。

大多数电脑显示器的刷新频率是60Hz,大概相当于每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此,最平滑动画的最佳循环间隔是1000ms/60,约等于16.6ms。

而setTimeout和setInterval的问题是,它们都不精确。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行。

requestAnimationFrame采用系统时间间隔,保持最佳绘制效率,不会因为间隔时间过短,造成过度绘制,增加开销;也不会因为间隔时间太长,使用动画卡顿不流畅,让各种网页动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。

特点

  • requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率。

  • 在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存使用量。

  • requestAnimationFrame是由浏览器专门为动画提供的api,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。

用法

requestAnimationFrame方法将一个callback作为参数,回调函数会被传入一个参数,DOMHighResTimeStamp,指示当前被 requestAnimationFrame() 排序的回调函数被触发的时间。返回值是一个请求 ID,表示回调列表中唯一的标识。可以传这个值给 window.cancelAnimationFrame() 以取消回调函数。

requestID = window.requestAnimationFrame(callback);

利用这个api,可以将某些代码放到下一次重新渲染时执行,避免短时间内触发大量reflow。

例如页面滚动事件(scroll)的回调函数就很适合使用这个api, 将回调操作推迟到下一次重新渲染。但需要注意的是requestAnimationFrame 不管理回调函数,即在回调被执行前,多次调用带有同一回调函数的 requestAnimationFrame,会导致回调在同一帧中执行多次。最简单的,可以用节流函数来解决这个问题,也可以想办法让requestAnimationFrame的队列里同样的回调函数只有一个:

let scheduledAnimationFrame = false;
document.body.onscroll = () => {
    if (scheduledAnimationFrame) return;
    scheduledAnimationFrame = true;
    window.requestAnimationFrame(() => {
        scheduledAnimationFrame = false;
        // do something
    });
};

当然,最佳的应用场景还是在帧动画里,可以大幅优化性能。

面试题

如何渲染几万条数据并不卡住界面

这道题考察了如何在不卡住页面的情况下渲染数据,也就是说不能一次性将几万条都渲染出来,而应该一次渲染部分 DOM,那么就可以通过 requestAnimationFrame 来每 16 ms 刷新一次。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta Http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <ul>控件</ul>
  <script>
    setTimeout(() => {
      // 插入十万条数据
      const total = 100000
      // 一次插入 20 条,如果觉得性能不好就减少
      const once = 20
      // 渲染数据总共需要几次
      const loopCount = total / once
      let countOfRender = 0
      let ul = document.querySelector("ul");
      function add() {
        // 优化性能,插入不会造成回流
        const fragment = document.createDocumentFragment();
        for (let i = 0; i < once; i++) {
          const li = document.createElement("li");
          li.innerText = Math.floor(Math.random() * total);
          fragment.appendChild(li);
        }
        ul.appendChild(fragment);
        countOfRender += 1;
        loop();
      }
      function loop() {
        if (countOfRender < loopCount) {
          window.requestAnimationFrame(add);
        }
      }
      loop();
    }, 0);
  </script>
</body>
</html>

兼容性

一些老的浏览器是不支持这个api的,为了也能使用这个api, 可以自定义这个方法,挂载到window下面:

(function() {
    var lastTime = 0;
    var vendors = ['WEBkit', 'moz'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame =
          window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

感谢你能够认真阅读完这篇文章,希望小编分享的“HTML5定时器requestAnimationFrame怎么用”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网html频道,更多相关知识等着你来学习!

--结束END--

本文标题: HTML5定时器requestAnimationFrame怎么用

本文链接: https://www.lsjlt.com/news/75679.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • HTML5定时器requestAnimationFrame怎么用
    这篇文章主要介绍了HTML5定时器requestAnimationFrame怎么用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前言计时器一...
    99+
    2022-10-19
  • html5如何制作新增的定时器requestAnimationFrame
    这篇文章主要介绍了html5如何制作新增的定时器requestAnimationFrame,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 ...
    99+
    2022-10-19
  • Jmeter固定定时器怎么使用
    这篇文章主要讲解了“Jmeter固定定时器怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Jmeter固定定时器怎么使用”吧!Jmeter之固定定时器的使用 Jmeter的线程组在发送...
    99+
    2023-06-21
  • nodejs的定时器怎么用
    这篇文章给大家分享的是有关nodejs的定时器怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 看一下定时器的使用。 int main()    v...
    99+
    2022-10-19
  • Python定时器怎么使用
    这里我们开发一个print_datetime函数来打印当前的时间,同时也将print_time函数作为我们需要一直保持执行的任务。# Importing the datetime module. import datetime def ...
    99+
    2023-05-14
    Python
  • android定时器怎么使用
    Android中有多种方式可以使用定时器,以下是其中两种常用的方法:1. 使用Handler的postDelayed方法Handle...
    99+
    2023-05-25
    android定时器 android
  • Linux定时器cron怎么用
    这篇文章将为大家详细讲解有关Linux定时器cron怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。crond 是linux下用来周期性的执行某种任务或等待处理某些事件的一个守护进程,与windows...
    99+
    2023-06-28
  • 怎么用mysql自带的定时器定时执行sql
    本篇内容主要讲解“怎么用mysql自带的定时器定时执行sql”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么用mysql自带的定时器定时执行sql”吧!需求每...
    99+
    2023-03-02
    mysql sql
  • vue怎么设置定时器和清理定时器
    本篇内容介绍了“vue怎么设置定时器和清理定时器”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!设置定时器和清理定时器使用钩子函数对定时器进行...
    99+
    2023-06-30
  • js定时器setInterval怎么使用
    setInterval函数是JavaScript中的定时器函数,用于按照指定的时间间隔重复执行指定的代码。```setInterva...
    99+
    2023-09-14
    js
  • java中Timer定时器怎么用
    小编给大家分享一下java中Timer定时器怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!Timer定时器的使用和启动1.概述定时计划任务功能在Java中主...
    99+
    2023-06-22
  • Python定时器Timer怎么使用
    在Python中,可以使用`Timer`类实现定时器功能。`Timer`类位于`threading`模块中,可以创建一个定时器对象,...
    99+
    2023-10-26
    Python
  • Android定时器Timer怎么使用
    Android定时器Timer可以使用以下步骤:1. 创建一个Timer对象Timer timer = new Timer();2....
    99+
    2023-05-30
    android定时器 android
  • Go怎么编写定时器与定时任务
    这篇文章主要介绍“Go怎么编写定时器与定时任务”,在日常操作中,相信很多人在Go怎么编写定时器与定时任务问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Go怎么编写定时器与定时任务”的疑惑有所帮助!接下来,请跟...
    99+
    2023-07-02
  • Linux中Timer定时器怎么使用
    在Linux中,可以使用timer_create函数创建一个定时器,然后使用timer_settime函数设置定时器的间隔和触发方式...
    99+
    2023-10-26
    Linux
  • AngularJs定时器$interval和$timeout怎么用
    这篇文章给大家分享的是有关AngularJs定时器$interval和$timeout怎么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。$intervalwindow.setI...
    99+
    2022-10-19
  • JavaScript清除定时器怎么使用
    这篇文章主要介绍“JavaScript清除定时器怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JavaScript清除定时器怎么使用”文章能帮助大家解决问题...
    99+
    2022-10-19
  • Android常用定时器怎么实现
    Android常用的定时器实现有以下几种方式:1. 使用Handler和Runnable实现定时器:```java// 创建Hand...
    99+
    2023-08-18
    Android
  • HTML怎么停止定时器
    这篇“HTML怎么停止定时器”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“HTML怎么停止...
    99+
    2022-10-19
  • java定时器怎么设置
    在Java中,可以使用`java.util.Timer`类来创建定时器。下面是一个简单的示例,展示了如何使用Timer类设置一个定时...
    99+
    2023-08-30
    java
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作