文章目录
一、BOM 概述
BOM 即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。
BOM 由一系列相关的对象构成,并且每个对象都提供了很多的方法和属性。但是 BOM 缺乏标准,兼容性差,JavaScript 语法的标准化组织是 ECMA,DOM 的标准化组织是 W3C,BOM 最初是 Netscape 浏览器标准的一部分。
① 把浏览器当做一个对象来看待;
② BOM 的顶级对象是 window;
③ BOM 学习的是浏览器窗口交互的一些对象;
④ BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差。
BOM 比 DOM 更大,它包含了 DOM!
① window 对象是浏览器的顶级对象,它具有双重角色;
② 它是 JS 访问浏览器窗口的一个接口;
③ 它是一个全局变量,定义在全局作用域中的变量,函数都会变成 window 对象的属性和方法;
④ 只不过在调用的时候可以省略 window,前面学习的对话框也都属于 window 对象方法
二、常见事件
1.页面加载事件
① 文档内容完全加载完触发
window.onload 是窗口(页面)加载事件,当文档内容完全加载完后才会触发该事件。(包括样式表、图片等)
//窗口加载事件
window.onload = function() {};
//或者
window.addEventListener("load", function() {});
注意:
① 有了 window.onload 就可以把JS 代码写到页面元素的上方,因为 onload 是等页面内容全部加载完毕,再去执行处理函数;
② window.onload 传统注册事件方式只能写一次,如果有多个,会以最后一个 window.onload 为准;
③ 如果使用 addEventListener 则没有次数限制。
window.addEventListener('load', fn);
function fn() {
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
alert('点击我!');
});
}
② 仅当 DOM 加载完触发
DOMContentLoaded 事件仅当 DOM 加载完成时触发。(不包括样式表、图片等)
如果页面很多的话,从用户访问到 onload 触发可能会需要较长的时间,交互效果就不能很好地实现,必然影响到用户的体验,此时用 DOMContentLoaded 事件比较合适。
document.addEventListener('DOMContentLoaded', function() {
alert('小兔崽子?');
})
2.调整窗口大小事件
window.onresize 是调整窗口大小的事件,当触发时就会调用处理函数。
window.onresize = function() {};
//或者
window.addEventListener('resize', function() {});
注意:
① 只要窗口大小发生像素变化,就会触发这个事件;
② 我们经常利用这个事件完成响应式布局;
③ window.innerWidth 获得当前屏幕的宽度。
window.addEventListener('load', function() {
var div = document.querySelector('div');
window.addEventListener('resize', function() {
if (window.innerWidth <= 800) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
})
})
三、定时器
① setTimeout() 定时器
该方法用于设置一个定时器,定时器到期后执行调用函数(只调用一次)。
window.setTimeout(调用函数, 延迟的毫秒数);
① 这个 window 在调用的时候可以省略;
② 这个延时单位是毫秒,但是可以省略,如果省略默认是0;
③ 页面中可能有很多的定时器,我们经常给定时器加标识符(名字);
④ 我们可以叫它定时炸弹。
//案例 5秒后自动关闭广告
<img src="images.jpg" class="ad"/>
<script>
var ad = document.querySelector('.ad');
function callback() {
ad.style.display = 'none';
}
setTimeout(callback, 5000);
</script>
② clearTimeout() 清除定时器
清除定时器括号里面跟的就是计时器的名字!
//案例 点击按钮定时停止
<button>点击停止定时器</button>
<script>
var btn = document.querySelector('button');
var timer = setTimeout(function() {
console.log('爆炸啦!');
}, 5000);
btn.addEventListener('click', function() {
clearTimeout(timer);
});
</script>
③ setInterval() 定时器
与上面方法不同的是,setInterval() 方法重复调用一个函数,每隔这个时间,就去调用一次回调函数(重复调用多次)。
window.setInterval(回调函数, 间隔的毫秒数);
① 同样这里的 window 可以省略;
② 单位是毫秒,不写默认是0;
③ 也要给定时器赋值一个标识符;
④ 回调函数可以直接写 callback,也可以写 ’ callback() '。
//案例 手动开始、停止定时器
<button class="begin">开始定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null;
begin.addEventListener('click', function() {
timer = setInterval(function() {
console.log('I love you.');
}, 1000);
});
stop.addEventListener('click',function() {
clearInterval(timer);
});
</script>
没有秒数变化用 setTimeout(),想要有秒数变化的效果就用 setInterval()!
1.倒计时效果
案例分析:
① 这个倒计时是不断变化的,因此需要定时器来自动变化。
② 三个黑色盒子里面分别存放时分秒。
③ 利用 innerHTML 将计算好的时分秒放入三个黑盒子里面。
<!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;
}
div {
width: 190px;
margin: 100px auto;
}
span {
display: inline-block;
width: 50px;
height: 50px;
background-color: black;
color: aliceblue;
font-size: 27px;
text-align: center;
line-height: 50px;
margin: 0 1px;
}
</style>
</head>
<body>
<div>
<span class="hour"></span>
<span class="minute"></span>
<span class="second"></span>
<div>
<script>
var hour = document.querySelector('.hour');
var minute = document.querySelector('.minute');
var second = document.querySelector('.second');
var times = '2022-10-01 18:30:00';
//先调用一次函数,防止页面刷新时有空白
countDown(times);
setInterval('countDown(times)', 1000);
//倒计时函数
function countDown(time) {
var nowTime = +new Date();
var inputTime = +new Date(time);
var times = (inputTime - nowTime) / 1000;
var d = parseInt(times / 60 / 60 /24);
d = d < 10 ? '0' + d : d;
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>
运行结果:
上面是倒计时案例的全部代码,倒计时不清楚的可以看我前面 JS 对象里面的日志对象,先自己动手写一遍,实际开发中直接搬过来用就可以!
特别注意,为防止页面刷新时有空白,先调用一次函数再倒计时!
2.短信倒计时
案例分析:
① 按钮点击之后,会禁用发送按钮,disabled 为 true。
② 同时按钮里面的内容会变化,注意 button 里面的内容通过 innerHTML 修改。
③ 里面的秒数是有变化的,因此需要用到定时器。
<!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;
}
div {
width: 400px;
height: 30px;
margin: 100px auto;
}
button {
width: 65px;
height: 23px;
background-color: rgb(168, 165, 165);
color: black;
}
</style>
</head>
<body>
<div>
<input type="text"/>
<button>提交</button>
</div>
<script>
var i = 5;
var btn = document.querySelector('button');
btn.addEventListener('click', fn);
function fn() {
btn.disabled = true;
countDown();
var timer = setInterval(countDown, 1000);
function countDown() {
if (i === 0) {
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '提交';
i = 5;
} else {
btn.innerHTML = i + '秒后重试';
i--;
}
}
}
</script>
</body>
</html>
注意倒计时完了之后 i 要恢复到初始值,保证下一次点击!
3.this 指向问题
this 的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定 this 到底指向谁,一般情况下 this 最终指向的是 那个调用它的对象。
① 全局作用域或者普通函数中,this 指向全局对象 window;
② 注意定时器里面的 this 也指向 window;
③ 方法调用中,this 指向方法的调用者;
④ 构造函数中,this 指向的是构造函数的实例;
四、JS 执行队列
1.同步和异步
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 JavaScript 这门脚本语言诞生的使命所致 —— JS 是为处理页面中用户的交互,以及操作 DOM 而诞生的。
单线程就意味着,所有的任务都需要排队,前一个任务结束,才会执行下一个任务,这样所导致的问题是,当 JS 执行时间过长时,页面的渲染就会不连贯,导致页面渲染加载阻塞。
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程,于是就出现了同步和异步。
① 同步,前一个任务结束后再执行后一个任务,程序的执行顺序和任务的排列顺序是一致的、同步的;
② 异步,执行一个任务的同时,还可以去处理其他的任务,也就是说,如果一个任务的执行时间比较长,我们就可以先执行下一个任务。
它们的本质区别是,这条流水线上各个流程的执行顺序不同!
2.任务执行过程
① 同步任务
同步任务都在主线程上执行,形成一个执行栈。
② 异步任务
JS 的异步任务是通过回调函数实现的,相关回调函数都添加到任务队列中。一般而言,异步任务有以下三种类型:
(1)普通事件,如 click、resize 等;
(2)资源加载,如 load、error 等;
(3)定时器,包括 setInterval、setTimeout 等。
① 同步任务在执行栈,异步任务在任务队列;
② 先执行同步任务,同步任务执行完毕后,系统会按次序读取任务队列中的异步任务,被读取到的异步任务依次进入到执行栈,开始执行任务。
先执行同步任务,再执行异步任务!
五、location 对象
window 对象给我们提供了一个 location 属性用于获取或设置窗体的 URL,并且可以用于解析 URL,因为这个属性返回的是一个对象,所以我们将这个属性称为 location 对象。
1.URL 简介
URL 统一资源定位符是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL 的一般语法格式:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name-andy&age=10#link
2.常见属性
通过这些属性可以得到地址中的各个部分!
重点记住,href 和 search!
3.自动跳转页面
案例分析:
① 利用定时器做倒计时效果。
② 时间到了就跳转页面,使用 location.href。
<!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>
</head>
<body>
<button>点击</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', fn);
function fn()
{
var timer = 5;
btn.style.display = 'none';
countDown();
setInterval(countDown, 1000);
function countDown() {
if (timer == 0){
location.href = 'http://www.itcast.cn';
} else {
div.innerHTML = '您将在'+ timer +'秒后跳转到首页';
timer--;
}
}
}
</script>
</body>
</html>
4.获取 URL 参数
案例分析:
① 第一个登录页面,里面有提交表单,action 提交到 index.html 页面。
② 第二个页面,可以利用第一个页面的参数,实现一个数据在不同页面之间的传递效果。
③ 核心思路,利用 URL 里面的 location.search 属性,返回数据参数。
④ 第一步去掉 ?,利用 substr。
⑤ 第二步利用 = 号分隔键和值,split(‘=’)。
<!--原文件-->
<!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>
</head>
<body>
<form action="index.html">
用户名:<input type="text" name="uname"/>
<input type="submit" value="登录"/>
</body>
</html>
<!--跳转文件-->
<!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>
</head>
<body>
<div></div>
<script>
//去掉问号
var params = location.search.substr(1);
//利用等号分隔符把字符串分隔成一个数组
var arr = params.split('=');
var div = document.querySelector('div');
div.innerHTML = arr[1] + '欢迎你!';
</script>
</body>
</html>
5.常见方法
① 前两个都能实现跳转页面,参数是跳转地址,location.assign() 记录浏览历史,也就是说可以实现后退功能;
② location.reload(true) 可以强制刷新页面。
六、navigator 对象
navigator 对象包含了有关浏览器的信息,它有很多属性,我们最常用的是 userAgent,该属性可以返回客户机发送服务器的 user-agent 头部的值。
下面代码可以判断用户使用哪个终端打开的页面,实现跳转:
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 = ""; //跳转到手机端的页面
} else {
window.location.href = ""; //跳转到pc端的页面
}
不需要记,用的时候复制粘贴就行!
七、history 对象
window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户在浏览器窗口中访问过的 URL。
<button>返回上一页</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click',function() {
history.go(-1);
})
</script>
history 对象一般在实际开发中很少用,但是会在一些 OA 办公系统中见到!