JavaScript - BOM 操作

一、窗口加载事件

1
2
3
window.onload = function(){};

window.addEventListener('load', function(){});

1. window.onload

window.onload : 窗口(页面)加载事件,当页面完成加载后直接触发事件,就调用的处理函数

::: warning

  • 有了 window.onload,就可以把 JS 代码放到页面元素的任何地方,因为 onload 是页面加载完成后才调用的函数
  • 页面有多个 window.onload 时,以最后一个为准

:::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
// onload 可以使 函数在 页面加载完成后再执行,所以可以使JS 代码放到页面的任何位置
window.onload = function () {
var but = document.querySelector('button');
but.addEventListener('click', function(){
alert('弹框1')
})
}
// 如果有多个 onload 时,以最后一个为准
window.onload = function () {
alert('弹框2')
}
</script>
<div class="demo">
<button>点击</button>
</div>

2. addEventListener

注意:

  • 没有数量限制,JS 代码可以放在页面任意位置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<script>
// addEventListener 使 load 方法没有数量限制
window.addEventListener('load', function () {
var but = document.querySelector('button');
but.addEventListener('click', function () {
alert('弹框1')
})
})
window.addEventListener('load', function () {
alert('弹框2')
})

</script>
<div class="demo">
<button>点击</button>
</div>

3. DOMContentLoaded

DOMContentLoaded : DOM 加载完成后即可触发,不用等待 图片、视频等资源加载

1
2
3
document.addEventListener('DOMContentLoaded', function(){
alert('不用等待页面资源加载')
})

load 与 DOMContentLoaded 的区别:

  • load 等页面内容全部加载完毕,包含页面dom元素 图片 flash css 等等
  • DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些

二、 调整窗口大小事件

1
2
3
window.onresize = function(){};

window.addEventListener('resize', function(){});

window.onresize : 调整窗口大小加载事件,当触发时就调用的处理函数

注意:

  • 只要窗口大小改变,就会触发这个事件
  • 常利用这个事件完成响应式布局
    • window。innerWidth : 获取当前窗口的宽度
1
2
3
4
5
6
7
8
9
10
11
12
<div class="demo">	
</div>
<script>
var div = document.querySelector('.demo');
window.addEventListener('resize', function(){
if (window.innerWidth <= 900){
div.style.display = 'none';
}else{
div.style.display = 'block';
}
})
</script>

三、 定时器

1. setTimeout

语法:

1
window.setTimeout(调用函数, [延迟的毫秒数]);

setTimeout : 用于设置一个定时器,该 定时器 在 定时到期 后 执行函数

::: warning

  1. window 在调用时可以省略不写
  2. 延时时间的单位为 毫秒,省略延时时间,则默认为0;
  3. 调用的函数可以直接写,也可以写函数名;
  4. 多个定时器时,可以使用不同的变量接收;

    :::

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div class="demo">	
</div>
<script>
var div = document.querySelector('.demo');
// 直接写入 函数
setTimeout(() => {
console.log('3s之后消失');
div.style.display = 'none';
}, 3000);
// 用 函数名 调用
setTimeout(block, 5000);
function block (){
console.log('5s之后出现');
div.style.display = 'block';
}
var time1 = setTimeout(() => {
console.log('计时器1');
})
var time2 = setTimeout(() => {
console.log('计时器2');
})
</script>

停止 计时器

语法:

1
window.clearTimeout(计时器标识符)
1
2
3
4
5
6
7
8
9
var st = setTimeout(() => {
div.style.display = 'none';
}, 5000);

// 停止倒计时
but.addEventListener('click', function(){
clearTimeout(st)
})

2. setInterval

setInterval() : 每过固定的时间,调用一次 函数

语法:

1
window.setInterval(回调函数, [间隔的毫秒数])
  • window 可以省略
  • 调用的函数 可以直接写,也可以写函数名
  • 间隔时间单位为 毫秒 ,不行默认为0
  • 可以用变量接收计时器
1
2
3
4
var st1 = setInterval(() => {
--i;
div.innerHTML = i + '<span>X</span> <button> 停止倒计时</button>';
}, 1000);

停止定时器 (clearInerval

语法:

1
window.clearInterval(intervalID)

案例 —- 倒计时

::: details

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-style: normal;
}

li {
list-style: none;
}

@font-face {
font-family: 'iconfont';
/* Project id 2303857 */
src: url('//at.alicdn.com/t/font_2303857_w55dl274uko.woff2?t=1640252281330') format('woff2'),
url('//at.alicdn.com/t/font_2303857_w55dl274uko.woff?t=1640252281330') format('woff'),
url('//at.alicdn.com/t/font_2303857_w55dl274uko.ttf?t=1640252281330') format('truetype');
}

.demo {
width: 168px;
height: 237px;
background-color: #F74630;
margin: 100px auto;
overflow: hidden;
}

.box {
width: 122px;
height: 123px;
margin: 46px 22px 17px;
}

.box h2 {
height: 40px;
color: #fff;
text-align: center;
font-size: 30px;
}

.box h6 {
height: 20px;
font-size: 17px;
text-align: center;
color: #ccc;
}

.box span {
display: block;
font-family: 'iconfont';
content: '\e6da';

height: 40px;
color: rgb(139, 230, 20);
font-size: 40px;
}

.box em {
display: block;
height: 17px;
font-size: 15px;
color: #fff;
text-align: center;
}

.times {
position: relative;
height: 40px;
width: 122px;
margin: 0 22px;
}


.bgc li {
float: left;
width: 35px;
height: 16px;
background-color: #333;
margin: 1px 2px 0;
}

.time li {
float: left;
color: #fff;
font-size: 18px;
font-weight: 700;
}

.time li:nth-child(1) {
position: absolute;
left: 10px;
top: 5px;
}

.time li:nth-child(2) {
position: absolute;
left: 47px;
top: 5px;
}

.time li:nth-child(3) {
position: absolute;
left: 86px;
top: 5px;
}
</style>
</head>

<body>
<div class="demo">
<div class="box">
<h2>京东秒杀</h2>
<h6>FLASH DEALS</h6>
<span></span>
<em>本场距离结束还剩</em>
</div>
<div class="times">
<ul class="bgc">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="time">
<li></li>
<li></li>
<li></li>
</ul>
</div>

</div>
<script>
var lis = document.querySelector('.time').querySelectorAll('li');
var inputTime = +new Date('2021-12-24 18:03:00');

function conutDown() {
var nowTime = +new Date();
var times = (inputTime - nowTime) / 1000; // 剩余时间的总秒数

var h = parseInt(times / 60 / 60 % 24);
h = h < 10 ? '0' + h : h;
lis[0].innerHTML = h;
var m = parseInt(times / 60 % 60);
m = m < 10 ? '0' + m : m;
lis[1].innerHTML = m;
var s = parseInt(times % 60);
s = s < 10 ? '0' + s : s;
lis[2].innerHTML = s;
}
setInterval(function () {
if (parseInt(lis[0].innerHTML) == 0 && parseInt(lis[1].innerHTML) == 0 && parseInt(lis[2].innerHTML) == 0){
lis[0].innerHTML = '00';
lis[1].innerHTML = '00';
lis[2].innerHTML = '00';
return false;
}else {
conutDown();
}
}, 1000)
</script>
</body>

</html>

:::

案例 —- 验证码发送

::: details

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html lang="zh">
<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></title>
<style type="text/css">

</style>
</head>
<body>
<div class="demo">
<input type="text" name="" id="yv" value="" />
<input type="button" name="" id="fs" value="发送验证码" />
</div>
<script type="text/javascript">
var fs = document.querySelector('#fs');
var time = 5;
fs.addEventListener('click', function(){
fs.disabled = true;
var si = setInterval(function(){
if (time > 0){
fs.value = '验证码 ' + time + 's 后可以再次发送';
time--;
}else{
clearInterval(si);
fs.value = '发送验证码';
fs.disabled = false;
time = 5;
}
}, 1000)
})
</script>
</body>
</html>

:::

3. this 的指向问题

::: note

  1. 全局作用域或者普通函数中 this 指向全局对象 window
    1. 定时器里面的 this 指向 window
  2. 方法中的 this ,谁调用就 指向 谁

:::

四、 JS执行机制

1. 同步 和 异步

同步 : 程序的执行顺序与任务的排列顺序一致,前一个任务结束后才会执行下一个任务;

异步 : 在执行一个任务的同时执行另一个任务

同步任务:

  • 同步任务都在主线程上执行,形成一个 执行栈

异步任务:

  • JS 的异步 是通过 回调函数实现的
  • 包含:普通事件(click、resize等)、资源加载(load、error等)、定时器(setInterval、setTimeout等)

2. JS 执行 机制

事件循环

  • 当主线程的同步任务执行完成后,会不断的去获取异步任务再到主线程执行

五、 location 对象

location : 用于获取 或 设置 窗体的 URL,并解析 URL

1. URL

URL 的一般语法格式:

1
2
3
protocol://host[:port]/path/[?query]#fragment

http://www.itcast.cn/index.html?name=andy&age=18#link
组成说明
protocol通讯协议(http、https)
host主机域名(www.pupper.cn)
port端口号(可选,http 的默认端口为 80)
path路由(由 0 到 多个 “/“ 隔开的字符串,一般为主机文件地址)
query参数 (以键值对的形式,通过 “&” 符号分割开来
fragment片段 “#” 后面的内容,常见于连接锚点

2. location 对象属性

对象属性返回值
location.href获取 或者 设置 整个 URL
location.host返回 注意域名(www.pupper.cn)
location.port返回 端口号 (如果未写,则返回 空字符串)
location.pathname返回 路径
location.search返回 参数
location.hash返回 片段 ( # 后面的内容,常见于连接 锚点)

案例 —- 页面自动跳转

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div class="demo">
<button type="button">点击</button>
</div>
<script type="text/javascript">
var but = document.querySelector('button');
var div = document.querySelector('.demo');
var time = 5;
but.addEventListener('click', function(){
var si = setInterval(function () {
if(time > 0){
div.innerHTML = time + 's 后跳转页面。';
time--;
}else{
location.href = 'https://pupper.cn';
clearInterval(si);
}
}, 1000)
})
</script>

案例 —- 不同页面参数获取


1
2
3
4
5
6
<div class="demo">
<form action="demo2.html">
<input type="text" name="uname" id="" value="" placeholder="请输入用户名"/>
<input type="submit" value="登录" id="login"/>
</form>
</div>

</code-block>

1
2
3
4
5
6
7
8
9
10
11
<div class="demo">
欢迎
<span></span>
登录
</div>
<script type="text/javascript">
var sp = document.querySelector('span');
var uname = location.search;
var un = uname.slice(1).split('='); // ['uname', '123']
sp.innerHTML = un[1]
</script>

</code-block>
</code-group>

3. location 对象 方法

对象方法返回值
location.assign()和 href 一样,可跳转页面(重定向页面),
记录历史,可以后退页面
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮 或 F5
(如果参数为 true ,强制刷新 ctrl + F5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<div class="demo">
<button type="button" class="but1">assign(可以后退页面)</button>
<button type="button" class="but2">replace(不能后退页面)</button>
<button type="button" class="but3">relode(刷新页面)</button>
<button type="button" class="but4">relode(强制刷新页面)</button>
</div>
<script type="text/javascript">
var but1 = document.querySelector('.but1');
var but2 = document.querySelector('.but2');
var but3 = document.querySelector('.but3');
var but4 = document.querySelector('.but4');

but1.addEventListener('click', function() {
location.assign('https://www.baidu.com');
});
but2.addEventListener('click',function () {
location.replace('http://pupper.cn');
});
but3.addEventListener('click',function () {
location.reload();
});
but4.addEventListener('click',function () {
location.reload(true);
});
</script>

五、 navigator 对象

navigator : 对象包含有关 浏览器 的所有信息

userAgent : 包含了用户的浏览器信息

案例 —- 根据用于浏览器信息,跳转pc页面或手机页面

1
2
3
4
5
if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
window.location.href = "../H5/index.html"; //手机
}else {
window.location.href = "../P/index.html"; //电脑
}

六、 history 对象

history : 与浏览器的 历史记录 进行交互,该对象包含用户 访问过的URL

对象方法作用
back()后退
forward()前进
go(参数)前进后退弄能,参数如果是 1 ,则前进一个页面,
如果是 -1 ,则后退一个页面


1
2
3
4
5
6
7
8
9
10
  <div class="demo">
<a href="demo2.html">点击我页面跳转</a>
<button type="button">前进</button>
</div>
<script type="text/javascript">
var but = document.querySelector('button');
but.addEventListener('click', function(){
history.forward();
} )
</script>

</code-block>

1
2
3
4
5
6
7
8
9
10
<div class="demo">
<a href="demo.html">点击我页面跳转</a>
<button type="button">后退</button>
</div>
<script type="text/javascript">
var but = document.querySelector('button');
but.addEventListener('click', function(){
history.back();
} )
</script>

</code-block>
</code-group>