写在前面
1.BOM概念
BOM(Browser Object Model)即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。
2.BOM构成
BOM的构成,比DOM更大,BOM包含DOM。
3.window
window对象是浏览器的顶级对象,具有双重角色:
(1)它是js访问浏览器窗口的一个接口。
(2)它是一个全局对象,定义在全局作用域中的变量,函数都会变成window对象的属性和方法。
<script>
// window.document.querySelector()
var num = 10;
console.log(num); //输出10
console.log(window.num); //输出10
function fn() {
console.log(11);
}
fn(); //输出11
window.fn() //输出11
</script>
一.window常见事件
1.窗口加载事件
(1)window..onload
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像,脚本文件,css文件等),就调用处理函数。
//传统写法
window.onload = function() {}
//监听写法
window.addEventListener("load",function(){});
注意:
1.有了window.onload
就可以把js代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。
2.window.onload
传统注册事件方式只能写一次,如果写多个,会以最后一个为准。
<script>
//第一次
window.onload = function() {
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
alert('点击我');
})
}
//第二次,会覆盖掉第一次的处理函数
window.onload = function() {
alert(22);
}
</script>
(2)DOMContentLoaded
DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
<script>
document.addEventListener('DOMContentLoaded', function() {
alert(33);
})
</script>
2.调整窗口大小事件
//传统方法注册
window.onresize=function() {}
//监听方法注册
window.addEventListener('resize', function(){})
注意:
1.只要窗口大小发生变化就会,触发这个事件。
2.我们经常利用这个事件完成响应式布局,window.innerWidth获取当前屏幕宽度
demo——当浏览窗口小于800像素隐藏div,大于800显示div
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<style>
div {
width: 200px;
height: 200px;
background-color: pink;
}
</style>
<script>
window.addEventListener('load', function () {
var div = document.querySelector('div');
window.addEventListener('resize', function () {
console.log(window.innerWidth);
if (window.innerWidth <= 800) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
})
})
</script>
</head>
<body>
<div></div>
</body>
</html>
3.定时器
(1)setTimeout()
window.setTimeout(函数, 延时时间);
setTimeout()方法用于设置一个定时器,该定时器在定时器记时结束后执行回调函数。
注:
- 这个window在调用的时候可以省略
- 这个延时时间单位是毫秒 但是可以省略,如果省略默认的是0
- 这个调用函数可以直接写函数名, 还有一个写法 函数名()
- 页面中可能有很多的定时器,我们经常给定时器加标识符 (名字)
<script>
setTimeout(function() {
console.log('2秒中到了'); }, 2000);
function callback() {
console.log('3秒种到了');
}
var timer1 = setTimeout(callback, 3000);
</script>
停止setTimeout()计数器
window.clearTimeout(timeouID)
clearTimeout()方法取消了先前通过调用setTimeout()建立的定时器。
<body>
<button>停止定时器</button>
<script>
var btn = document.querySelector('button');
//定义一个定时器
var time = setTimeout(function() {
console.log('5秒到了');
}, 5000);
//点击停止定时器
btn.addEventListener('click', function() {
clearTimeout(time);
})
</script>
</body>
(2)setInterval()
window.setInterval(函数, 延时时间);
setInterval()方法重复调用一个函数,每隔这个延迟时间,就去调用这个回调函数。
<script>
setInterval(function() {
console.log('继续输出');
}, 1000);
</script>
注:
用法和setTimeout()一样。
区别:
setTimeout 延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
setInterval 每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
demo——倒计时
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div {
margin: 200px;
}
span {
display: inline-block;
width: 40px;
height: 40px;
background-color: #333;
font-size: 20px;
color: #fff;
text-align: center;
line-height: 40px;
}
</style>
</head>
<body>
<div>
<span class="hour">1</span>
<span class="minute">2</span>
<span class="second">3</span>
</div>
<script>
// 1. 获取元素
var hour = document.querySelector('.hour'); // 小时
var minute = document.querySelector('.minute'); // 分钟
var second = document.querySelector('.second'); // 秒数
var inputTime = new Date('2020-6-23 19:00:00'); // 返回的是用户输入时间总的毫秒数
countDown(); // 先调用一次这个函数,防止第一次刷新页面有空白
// 2. 开启定时器
setInterval(countDown, 1000);
function countDown() {
var nowTime = new Date(); // 返回的是当前时间总的毫秒数
var times = (inputTime - nowTime) / 1000; // times是剩余时间总的秒数
var h = parseInt(times / 60 / 60 % 24); //时
h = h < 10 ? '0' + h : h;
hour.innerHTML = h; // 时
var m = parseInt(times / 60 % 60); // 分
m = m < 10 ? '0' + m : m;
minute.innerHTML = m;
var s = parseInt(times % 60); // 秒
s = s < 10 ? '0' + s : s;
second.innerHTML = s;
}
</script>
</body>
</html
停止setInterval()计数器
window.clearInterval(timeID)
demo
<body>
<button class="begin">开启定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var time = null; // 全局变量 null是一个空对象
begin.addEventListener('click', function() {
time = setInterval(function() {
console.log('hello');
}, 1000);
})
stop.addEventListener('click', function() {
clearInterval(time);
})
</script>
</body>
demo——短信验证码注册事件
分析:
按钮点击之后,按钮会禁用(disabled 为true)
同时按钮里面的内容会变化, 注意 button 里面的内容通过 innerHTML修改
里面秒数是有变化的,因此需要用到定时器
定义一个变量,在定时器里面,不断递减
如果变量为0,需停止定时器,并且复原按钮初始状态
<body>
手机号码: <input type="number"> <button>发送</button>
<script>
var btn = document.querySelector('button');
var time = 3; // 定义剩下的秒数
btn.addEventListener('click', function() {
btn.disabled = true;
var fun = setInterval(function() {
if (time == 0) {
// 清除定时器和复原按钮
clearInterval(fun);
btn.disabled = false;
btn.innerHTML = '发送';
time = 3;
} else {
btn.innerHTML = '还剩下' + time + '秒,可以重新获取';
time--;
}
}, 1000);
})
</script>
</body>
4.this指向问题
(1)全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
<body>
<button>点击</button>
<script>
console.log(this); //window
function fn() {
console.log(this);
}
window.fn(); //window
window.setTimeout(function() {
console.log(this); //定时器中的this也指向window
}, 1000);
</script>
</body>
(2)方法调用中谁调用this指向谁
<body>
<button>点击</button>
<script>
var o = {
sayHi: function() {
console.log(this); // this指向的是 o 这个对象
}
}
o.sayHi();
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
console.log(this); // this指向的是btn这个按钮对象
})
</script>
</body>
(3)构造函数中this指向构造函数的实例
function Fun() {
console.log(this); // this 指向的是fun 实例对象
}
var fun = new Fun();
二.JS执行队列
1.同步和异步
同步
前一个任务结束后再去执行后一个任务,程序执行顺序于任务的排列顺序是一致的,同步的。
异步
在做一件事的同时,还可以做其他事情。
2.同步任务和异步任务
同步任务
都在主线程上执行,形成一个执行栈。
异步任务
JS的异步通过回调函数实现的,异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。
一般异步任务包括
1.普通事件 如: click, resize等
2.资源加载 如 : load error等
3.定时器
三.BOM对象
1.location对象
window对象提供了location属性用于获取或者设置窗体的URL,并且可以用于解析URL,该属性返回的是一个对象,因此也称为location对象。
(1)URL组成
protocol://host[:port]/path/[?query]#fragment
名称 | 说明 |
---|---|
protocol | 通信协议 |
host | 主机(域名) |
port | 端口 |
path | 路径 |
query | 参数,以键值对的形式通过&符号来分隔开 |
fragment | 片段 #后面内容,常见于链接,锚点 |
(2)location对象的属性
对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个url |
location.host | 返回主机(域名) |
location.port | 返回端口号,如果未写,返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段,#后面内容,常见于链接,锚点 |
demo——自动跳转页面
<body>
<button>点击</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
//点击跳转
btn.addEventListener('click', function() {
location.href = 'http://www.baidu.com';
})
var timer = 9;
//时间跳转
setInterval(function() {
if (timer == 0) {
location.href = 'http://www.baidu.com';
} else {
div.innerHTML = '您将在' + timer + '秒钟之后跳转到首页';
timer--;
}
}, 1000);
</script>
</body>
(3)location对象的方法
对象方法 | 返回值 |
---|---|
location.assign() | 和href一样,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,不记录历史,所以不能后退 |
location.reload() | 重新加载页面,相当于刷新按钮或者f5,如果参数为true强制刷新,crl + f5 |
<body>
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
// 记录浏览历史,所以可以实现后退功能
// location.assign('http://www.baidu.com');
// 不记录浏览历史,所以不可以实现后退功能
location.replace('http://www.baidu.com');
//location.reload(true);
})
</script>
</body>
2.navigator对象
navigator对象包含有关浏览器的信息,其中最常用的是userAgent。
3.history对象
对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能,如果参数为1,页面前进1个页面,如果为-1后退一个页面。 |