BOM之定时器
JavaScript中的时间是通过定时器控制的,他们分别是window.setInterval和window.setTimeout,我们当然可以省略window,直接使用方法名称调用。
一 事件分类
在讲解定时器之前,我们需要先明白 JavaScript 中事件(任务)的分类。
JavaScript 把所有代码当做事件或任务来执行,由于 JavaScript 是单线程的,所以无论如何它都只能自上而下,一个一个的来执行任务,在做一件事时,不能干其他事,即同步。然而,随着时代的发展,异步的需求越来越多,浏览器(宿主环境)就为我们实现了异步执行任务的 API,本文即将要讲解的定时器就是典型的异步操作。
ECMAScript 是同步执行的,浏览器又实现了异步API,那么 JavaScript 是怎么保证他们不冲突的呢?事件分类解决了这个问题。
普通的 JavaScript 语句依然同步执行,但他们执行的地方在 JavaScript 主线程执行栈中,这些任务我们称作同步任务。
异步API 任务则在单独的线程任务队列中执行,这些任务我们称为异步任务。
这些任务在执行时保持主线程优先原则,即使异步任务满足不用等待立即执行的条件,也还是要等待同步任务执行完毕。
二 setTimeout
在等待指定的毫秒数后执行函数,语法如下:
setTimeout(code/function, milliseconds, param1, param2, ...)
方法接受2个或多个参数,第一个是一段JS代码或一个函数引用,第二个是需要等待的时间(以毫秒计),如果第一个参数是函数引用,并且需要传递参数,可以在后面依次传入。方法返回一个唯一id,代表该定时器,使用clearTimeout(id)可以清除定时器。
- setTimeout(functon(){
- console.log(new Date());
- },3000);
- console.log(new Date());
- //立即显示一次当前时间,3秒后又将显示一次
经测试发现:如果第一个参数是一段JS代码而非函数引用,该代码将立即被执行,而不会延时等待。
三 setInterval
等同于 setTimeout(),但持续重复执行该函数。语法如下:
setInterval(code/function, milliseconds, param1, param2, ...)
使用方法和setTimeout()相同。
- function timer(){
- var d = new Date();
- document.body.innerText = d;
- }
- setInterval(timer,1000);
上面是一个简单的定时器示例。
另外,setInterval方法有一个严重的缺陷,那就是不能确保执行时间的准确性。
在执行setInterval()时,假如我们设置每1s执行一次函数,但函数执行一次需要花费2s。浏览器会每隔1s就向一个事件队列中添加一个事件(即执行一次函数),当第一次执行完毕(3s之后了),这时队列中已经有2个事件正在排队了,于是浏览器立即执行第二个事件(等待队列中的第一个)。这样明显和我们本意每1s执行一次函数不符。所以在setInterval中,与其说第二个参数是延时时间,不如说是每个事件执行的最大间隔时间更为准确。因为当事件执行时间大于设置的间隔时间时,两个任务执行之间是没有间隔时间的。
有些书上表示,到了设置的时间点,如果上一次的函数还没执行完,那么本次事件将不会被添加到事件队列中去,这次事件将被跳过,直到未来设置的某一时间点,前面的任务已经完成,才向队列中添加下一个事件。但浏览器实际上是按照第一种方式管理事件队列的,即到了时间不管前面的是否执行完毕,都插入一个进去,然后依次等待执行。(我用的Chrome 76.0.3869.100测试)
setInterval主要应用在绘制动画效果上,鉴于它对时间的不准确性,要想获得完美的动画效果请使用CSS3的Animation实现。另外,如果确实需要使用,请务必把握好间隔时间的设置。下面是使用setInterval封装的一个运动函数:
- var timer;
- function startMove(obj,json,Fn){
- var key;
- clearInterval(timer);
- timer = setInterval(function(){
- for(var prop in json){//json是一个包含需要改变的属性和目标值的对象。
- var bridge;
- if(prop == 'opacity'){
- bridge = getStyle(obj,prop)*100;//为了便于计算,先放大100倍
- }else{
- bridge = parseInt(getStyle(obj,prop));
- }
- var speed = (json[prop] - bridge)/6;
- speed = speed > 0?Math.ceil(speed):Math.floor(speed);//这里为了获得更好的动画效果,动态设置了运动速度。你当然可以给一个常数作为运动速度
- if(prop == 'opacity'){
- obj.style[prop] = (bridge + speed) / 100;
- }else{
- obj.style[prop]= bridge + speed + 'px';
- }
- if(bridge != json[prop]){
- key = false;
- }else{
- key = true;
- }
- if(key){
- clearInterval(timer);
- if(Fn)Fn();//当目标运动完成,执行回调函数
- }
- }
- },30);
- }
- function getStyle(obj,prop){//获取css样式值
- if(obj.currentStyle){//IE
- return obj.currentStyle(prop);
- }else{//其他
- return getComputedStyle(obj,false)[prop];
- }
- }
BOM之定时器的更多相关文章
- BOM以及定时器
一.BOM 1.操作浏览器的一些方法 (浏览器对象模型) 2.window是is中的顶级变量,是一个全局的变量,所有人都可以访问到它,基本 的方法和属性 (document,alert,console ...
- 13 -1 BOM和定时器
一 BOM JavaScript基础分为三个部分: ECMAScript:JavaScript的语法标准.包括变量.表达式.运算符.函数.if语句.for语句等. DOM:文档对象模型,操作网页上的元 ...
- BOM心得-定时器
写在前面的话:之前一直以为定时器的返回值是Object类型,所以timer初始化也是写null,今天发现返回值是number,进而发觉这个返回值代表的是定时器的索引,指代这是第几个定时器 个人觉得只用 ...
- JS中定时器的返回数值ID值
定时器会返回一个数字值id,可以由clearInterval(id)或clearTimeout(id)来实现对对应定时器的清除. setInterval()/setTimeout()BOM中的Wind ...
- web前端面试第一次[定时器]
BOM中定时器--计时器 定时器参数两个:(函数,时间(单位ms(1000ms=1s))) 时间设置1s,每过1s执行一次函数 //设置定时器 setInterval(funtion(){ alert ...
- 前端3 — js — BOM没完( 不了解也行 )
1.js是什么? -- 英文全称javascript javaScript(简称"JS") 是一种具有函数优先的轻量级,解释型或即时编译型的编程语言.虽然它是作为开发Web页面的脚 ...
- Web前端学习路线
第一阶段: HTML+CSS:HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础:Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMAsc ...
- 关于web前端的学习路线
第一阶段: HTML+CSS:HTML进阶.CSS进阶.div+css布局.HTML+css整站开发. JavaScript基础:Js基础教程.js内置对象常用方法.常见DOM树操作大全.ECMAsc ...
- (1)写给Web初学者的教案-----学习Web的知识架构
1:学习Web的知识架构 前文中我们简单的介绍了一些关于Web的基本知识,这里任老师再次强调一下凡是用浏览器打开的网站我们就称之为Web应用程序(B/S结构).除此之外其它需要下载安装的软件或是手机 ...
随机推荐
- 使用docker快速搭建本地环境
在平时的开发中工作中,环境的搭建其实一直都是一个很麻烦的事情 特别是现在,系统越来越复杂,所需要连接的一些中间件也越来越多. 然而要顺利的安装好这些中间件也是一个比较费时费力的工作. 俗话说" ...
- JavaScript中一个方法同时发送两个ajax请求问题
今天在做项目中遇到一个问题,大概是在一个jsp页面同时有一个select下拉搜索条件框和一个Bootstrap表格展示列表.这两个都要通过ajax向后台拿数据,而且要在页面加载时完成.当时的做法是: ...
- net core WebApi——文件分片下载
目录 前言 开始 测试 小结 @ 前言 上一篇net core WebApi--文件分片上传与跨域请求处理介绍完文件的上传操作,本来是打算紧接着写文件下载,中间让形形色色的事给耽误的,今天还是抽个空整 ...
- 在.net core web项目中生成图片验证码
第1步:添加SkiaSharp包引用 Install-Package SkiaSharp 第2步:编写生成图片验证码的代码 using SkiaSharp; //在类文件头部添加引用 public I ...
- 计蒜客 蓝桥杯模拟 瞬间移动 dp
在一个 n \times mn×m 中的方格中,每个格子上都有一个分数,现在蒜头君从 (1,1)(1,1) 的格子开始往 (n, m)(n,m) 的格子走.要求从 (x_1,y_1)(x1,y1 ...
- yzoj P1122 阶乘 题解
T组数据,给出N,求出N!最右边非零的数. 对于30%的数据,N <= 30,T<=10. 对于全部的数据,N <= 10^2009,T<=30. 一道数学题 解析 N!/(1 ...
- 用PhpStrom线上连接修改linux服务器上代码配置
为了进一步提高自己的技能水平,不久前入手了一台服务器,不贵,一年也就不到两百,因为自己对于linux机器比较生疏,命令用的有点抠脚.老需要查阅处理. 于是我选择用PhpStrom直接连接线上服务器,通 ...
- docker 搭建自己的github
github 搭建: 自己搭建一个github网站(仓库) daocloud:公共hub搜索git下载github镜像 docker pull gitlab/gitlab-ce:8.7.0-r ...
- Go第三方日志库logrus
日志是程序中必不可少的一个环节,由于Go语言内置的日志库功能比较简洁,我们在实际开发中通常会选择使用第三方的日志库来进行开发.本文介绍了logrus这个日志库的基本使用. logrus介绍 Logru ...
- JSP标签介绍
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在Jsp页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码,造成jsp页面难以维护. jsp的常用标签有以下三个 <j ...