BOM导读
bom,即为,Browser Oject Model 就浏览器对象模型,BOM提供了独立于文档内容而与浏览器窗口进行交互的对象,其核新对象是 window.
window对象是浏览器的顶级对象,在js中,它是全局对象,js定义在全局作用域下的变量和函数都会变成window对象的属性和方法。
例如: 在全局作用域下num=10;
,其实会自动变成 window.num=10;
window 通常被省略。
window 常见事件
load 页面加载事件
我们前面写的js代码都是在我们要操作的元素之后的,原因就是,代码是从上往下加载,js写到前面的话,是获取不了后面的元素的。
学习了bom之后,我们可以把代码写在onlaod之内。 window.onload 是窗口页面加载事件,当文档内容完全加载(包括图像,脚本文件,css文件等)之后会触发该事件。
如何使用
-
传统注册方式
window.onload=function(){ // }
使用这种方法,load只能使用一次,写了多个只能以最后一个处理函数为准
-
addEventListener()函数
window.addEventListener('load',function(){ // });
DOMContentLoaded 窗口加载事件
仅dom加载完成时(不包括css,图片等)触发。
这个DOMContentLoaded 会比 load事件 先触发。
resize 窗口大小被调整
只要窗口发生像素变化,那么就会产生这个效果。
那么如何获取窗口大小呢?
window.innerWidth
窗口的文档显示区宽window.innerHeight
窗口的文档显示区的宽度。window.outerHeight
属性设置或返回一个窗口的外部高度,包括所有界面元素(如工具栏/滚动条)。window.outerWidth
属性设置或返回窗口的外部宽度,包括所有的界面元素(如工具栏/滚动)。
定时器
window对象有两个定时器
- setTimeout()
- setInterval()
window.setTimeout
()(window可以省略) 定时器
setTimeout(回调函数,[延迟毫秒数]);
这个方法时,执行到这一句的时候,会延后执行回调函数。
第二个参数默认值为0,就是立马执行。
setTimeout 不会阻碍后面的语句执行
虽然setTimeout会延迟{}语句执行,但是不会延迟后面的语句执行,仿佛和多线程一样。其实这个问题,后面就会说到,js的执行机制。
alert('验证');
setTimeout(function(){
alert('我会延后2秒出现');
},2000);
alert('settimeout 后面的语句不会收到他的延迟影响');
window.clearTimeout() 清除定时器
clearTimeout(定时器ID)
我们通常设置定时器的时候,需要给定时器起一个id
var timer= setTimeout(function(){
alert('我要被干掉了');
},50000);
clearTimeout(timer);
setInterval() 循环定时器定时器
setInterval(回调函数,[延迟毫秒数])
这个就是一个循环执行器,每隔延迟毫秒数就会调用回调函数。
clearInterval() 清除循环定时器
clearInterval(定时器ID)
用法和前面的clearTimeout(定时器ID)
一致
倒计时效果的实现
练习一下 setInterval();
<div class="timer">
<span class="day">1</span>天
<span class="hour">1</span>时
<span class="minute">1</span>分
<span class="scecond">1</span>秒
</div>
JavaScript的实现
var days = document.querySelector('.day');
var hours=document.querySelector('.hour');
var minutes = document.querySelector('.minute');
var sceconds= document.querySelector('.scecond');
function getRTime() {
var nowTime = +new Date();
var inputTime = +new Date('2021/04/25 00:00:00');
var times = nowTime > inputTime ? (nowTime - inputTime) / 1000 : (inputTime - nowTime) / 1000;
var day = parseInt(times / 60 / 60 / 24);
var hour = parseInt(times / 60 / 60 % 24);
var m = parseInt(times / 60 % 60);
var s = parseInt(times % 60);
day = day < 10 ? '0' + day : day;
hour = hour < 10 ? '0' + hour : hour;
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
days.innerHTML=day;
hours.innerHTML=hour;
minutes.innerHTML=m;
sceconds.innerHTML=s;
}
window.onload=getRTime();//防止页面刷新有空白的效果;
setInterval(getRTime, 1000);
js执行机制
同步和异步
js在最大特点时单线程的,没法多线程。但是H5标准提出web worker ,运行js建立类似多线程,但本质上还是单线程,于是js出现了同步执行环境和异步执行环境。
同步执行环境:串行执行任务,只有上一个任务执行完了才能执行下一任务
异步执行环境。:对于一些特殊任务,跳过等待,先处理后续的任务允许一个任务。
一般来说异步任务有下面三种类型
- 普通事件 ,click 、resize等,
- 资源加载 , load ,error
- 定时器,setInterval ,setTimeout
由于本质上还是单线程,所以产生了任务队列与事件循环,来协调主线程与异步模块之间的工作。
js 事件循环 event loop
js在执行这些任务的时候,有如下循序,
- 先一步一步的执行主线程任务,
- 遇到异步任务,先不直接执行交给 异步进程处理
- 异步进程 来判断,是否将相应的异步任务推入任务队列(异步队列);
- 等执行栈里的同步任务执行完了
- 查询任务队列,如果存在任务,则取出一个任务推入主线程处理(先进先出);
- 重复 1-5的步骤 ,这样的循环叫做 事件循环
我们还是那一段代码说话吧。
console.log(1);
setTimeout(function () {
console.log(3);
}, 1000);
document.onclick=function(){
console.log('我点击了');
}
console.log(2);
首先,同步任务就有,
console.log(1);
setTimeout(fn, 1000);
document.onclick=fn();
console.log(2);
在处理 setTimeout 和 onclick 的时候 ,就会把他们交给 异步进程处理,
在 1s之前,我们 的异步进程判断 console.log(3); 和 console.log('我点击了'); 没有到触发条件,所以不放到任务队列里面
最后 主线程上的任务都执行完了,他会看看任务队列有没有任务,发现没有就继续查询。
没到1s前,我们点击了,异步进程判断console.log('我点击了'); 该去任务队列里面了,那么任务队列就会多了个任务 console.log('我点击了'); ,由于主线程没有任务了,就会把任务队列里的任务推入到主线程里执行。
主线程有没有事情干了,有去看看 任务队列领任务了。
1s到了 那么异步进程也会把console.log(3);放入任务队列,后面的事情就和前面的一样了,不断循环。