BOM浏览器对象模型
BOM概述
什么是BOM
BOM的构成
BOM比DOM更大,它包含DOM
window对象的常见事件
window.onload窗口加载事件
1.window.onload:等页面全部加载完毕触发,包含dom元素 图片 flash css等
2.DomContentLoaded: 是DOM加载完毕事件被触发,不包含样式表,图片,flash,css和子框架的完全加载。
用法示例:
<script>
// 窗口加载事件:当文档内容完全完成才触发该事件;这样写script可以写在任意位置;
// 1.使用window.load传统注册方法只能写一次,多次则会以最后一次为准
// window.onload = function(){
// var btn = document.querySelector('button');
// btn.addEventListener('click', function(){
// alert('11515');
// })
// }
// 2.使用addEventListener则没有
window.addEventListener('load', function(){
var btn = document.querySelector('button');
btn.addEventListener('click', function(){
alert('11515');
})
})
window.addEventListener('load', function(){
alert('444');
})
//
document.addEventListener('DomContentLoaded', function(){
alert(33);
})//33 444 11515
// load等页面全部加载完毕,包含dom元素 图片 flash css等
// DOMContentLoaded 是DOM加载完毕事件被触发,不包含样式表,图片,flash,css和子框架的完全加载。
</script>
</head>
<body>
<button>按钮</button>
</body>
调整窗口大小事件
- 用法示例:当窗口小于900时,则隐藏盒子
<style>
div{
width: 200px;
height: 200px;
background-color: #bfa;
}
</style>
</head>
<body>
<script>
// 调整窗口大小事件:只要窗口像素大小发生变化,就会触发该事件
// - 没有css3时,常用来完成响应式布局
window.addEventListener('resize', function(){
console.log('变化了');
})
// 示例:当窗口小于900时,则隐藏盒子
window.addEventListener('load', function(){
var div = document.querySelector('div');
window.addEventListener('resize', function(){
console.log(window.innerWidth);
if(innerWidth<900){
div.style.display = 'none';
}else{
div.style.display = 'block';
}
})
})
</script>
<div></div>
</body>
两种定时器
setTimeout
(1)语法规范:window.setTimeout(调用函数,延时时间)
(2)这个window在调用的时候可以省略
(3)这个延时时间是毫秒ms,但是可以省略,省略时默认是0
(4)这个调用函数可以直接写函数,也可以写函数名
(5)页面中可能有很多定时器,所以通常给定时器加标识符(名字)
- clearTimeout(Timeout ID);清除定时器
用法示例:
<body>
<button>点击停止爆炸</button>
<script>
// setTimeout(function(){
// console.log('2s过了');
// }, 2000)
var btn = document.querySelector('button');
function boom(){
console.log('爆炸了');
}
var timer1 =setTimeout(boom, 2000);
var timer2 =setTimeout(boom, 2000);
//clearTimeout(Timeout ID);清除定时器
// -window也可省略;里面的ID就是定时器的标识符(名字)
btn.addEventListener('click', function(){
})//若点击,则停止了timer1的打印爆炸
</script>
</body>
回调函数
案例:5s后自动关闭的广告
案例代码:
<script>
window.addEventListener('load',function(){
var img = document.querySelector('img');
function callback(){
img.style.display = 'none';
}
setTimeout(callback, 5000)
})
</script>
</head>
<body>
<img src="../../images/adv.png" alt="">
</body>
setInterval
- 与setTimeout用法一致,不同于setInterval()方法是反复调用,而非一次则停止调用
- clearInterval(ID)清除定时器 ( 值得注意的是清除定时器时,定时器的标识符应该是全局变量,且为null)
- 代码示例:
案例:仿京东倒计时
案例代码:
<style>
.box {
overflow: auto;
margin: 150px;
text-align: center;
}
.box div {
float: left;
width: 60px;
height: 60px;
line-height: 60px;
background-color: rgb(49, 50, 49);
color: white;
margin: 2px;
}
</style>
</head>
<body>
<div class="box">
<div class="hour"></div>
<div class="min"></div>
<div class="sec"></div>
</div>
<script>
// 获取元素
var hour = document.querySelector('.hour');
var min = document.querySelector('.min');
var sec = document.querySelector('.sec');
var inputTime = +new Date('2022-7-30 19:00:00');//用户输入目标时间(截止时间点)
// 先调用一次这个函数,防止刷新会有空白(因为第一次执行也需要间隔)
countDown();
// 封装函数返回用户输入时间距离当前时分秒并开启定时器
setInterval(countDown, 1000);
function countDown() {
var nowTime = +new Date(); //返回的是当前时间总的毫秒数
times = (inputTime - nowTime) / 1000;//用户输入的时间到现在的总毫秒数
var h = parseInt(times / 60 / 60 % 24);//时
h = h < 10 ? h = '0' + h : h;
var m = parseInt(times / 60 % 60); //分
m = m < 10 ? m = '0' + m : m;
var s = parseInt(times % 60); //当前的秒
s = s < 10 ? s = '0' + s : s;
hour.innerText = h;
min.innerText = m
sec.innerText = s;
}
</script>
</body>
案例:发送短信
- 案例需求:点击发送后,发送按钮在一段时间内禁止点击
- 案例代码:
<body>
手机号码:<input type="number"><button>发送</button>
<script>
var btn = document.querySelector('button');
var x = 5;//此处修改从几开始倒数
btn.addEventListener('click', function () {
this.disabled = true;//this指向button
ban();
var timer = setInterval(ban, 1000);
//封装函数,点击按钮变成禁言且开始倒数
function ban() {
//判断等于0时,则回到可点击初始状态并清除定时器
if (x !== 0) {
x -= 1;
btn.innerText = '还剩' + x + '秒可继续发送';
} else {
clearInterval(timer);
btn.disabled = false;
btn.innerText = '发送';
x = 5;//这个5需要重新开始
}
}
})
</script>
</body>
this指向问题
- this的指向在函数定义的时候是确定不了的,
只有函数执行的时候才能确定this到底指向谁
,一般情况下this
的最终指向
的是那个调用它的对象
现阶段,我们先了解一下几个this指向:
- 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window )
- 方法调用中:谁调用this指向谁
- 构造函数中this指向构造函数的实例
<body>
<button>按钮</button>
<script>
// this指向问题:一般情况下this的最终指向的是调用它的对象
// 1.全局作用域或者普通函数中的this指向全局对象window (注意定时器里的this指向window)
console.log(this);//window
function fn(){
console.log(this);
}
fn();//window;等价于window.fn(),省略部分
window.setTimeout(function(){
console.log(this);
},1000)//window
// 2.方法调用中:谁调用this指向谁
var o = {
sayHi:function(){
console.log(this);//this指向的是o这个对象
}
}
o.sayHi();
var btn =document.querySelector('button');
btn.onclick = function(){
console.log(this);//指向button
}
// 3.构造函数中this指向构造函数的实例
function Fun(){
console.log(this);
}
var fun = new Fun(); //指向创建的空对象,实例化赋值给fun,所以指向fun
</script>
</body>
JS执行机制
JS单线程
同步和异步
什么是同步和异步
同步和异步任务执行过程
通过几个问题来理解同步和异步任务的执行过程
- 第一个问题:当给定时器设置1s延时:打印结果为1,2,3
- 第二个问题:如下把定时器延时改为0,打印结果仍为:1,2,3
- 同步任务和异步任务执行过程:
JS执行机制
- 文字理解JS执行机制:
JS原本是单线程,任务逐个执行,但某些任务如定时器等回调函数执行事件太长
;为了解决页面渲染不连贯,H5允许JS创建多线程
把任务分成同步任务
和异步任务
;
- JS获得任务时,把同步任务放入执行栈中逐个执行,把异步任务提交给对应的异步处理进程处理;
- 当任务触发(如点击了按钮,定时器时间到达),异步处理进程则会把异步任务
依次放入任务队列
中 - 当执行栈中的同步任务执行完毕,则按顺序执行异步任务
事件循环
:
location对象
前置知识储备:URL
什么是location对象
window对象给我们提供了一个location属性
用于获取或设置窗体的URL
,并且可以用于解析URL
。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象
。
location对象的属性
案例:5s之后自动跳转首页
- 案例需求:通过location的href属性实现点击按钮直接跳转或5s后自动跳转首页
- 案例代码:
<body>
<button>按钮</button>
<div></div>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
var time = 5;
btn.addEventListener('click', function () {
location.href = 'https://blog.youkuaiyun.com/SevgiliD?type=blog';
})
fn();//提前调用一次函数,避免刷新出现空白
var timer = setInterval(fn, 1000);
function fn(){
if (time !== 0) {
div.innerHTML = '您将在' + time + '秒钟之后跳转到首页';
time--;
} else {
clearInterval(timer);
location.href = 'https://blog.youkuaiyun.com/SevgiliD?type=blog';
}
}
</script>
</body>
案例:获取url的属性
- 案例需求:第一个页面提交的名字,会在另一个网页中获取
- 案例代码:
<!-- 注册页代码 -->
<body>
<form action="index.html">
用户名:<input type="text" name="uname">
<input type="submit" value="登录">
</form>
</body>
<!-- 登录页代码 -->
<body>
<div></div>
<script>
console.log(location.search);//?uname=andy
//1.先去掉? substr('起始位置',截取几个字符):被认作是遗留的函数并且可以的话应该避免使用
// var params =location.search.substr(1);//uname=andy
var params =location.search.substring(1);//uname=andy
console.log(params);
// 2.利用=把字符串分割为数组:split('=')
var arr = params.split('=');
console.log(arr);//0: "uname"1: "andy
var div =document.querySelector('div');
// 3.把数据 写入div中
div.innerHTML = arr[1] + '欢迎你';
</script>
</body>
location常见方法
- 用法示例:
<body>
<button>点击</button>
<script>
var btn =document.querySelector('button');
btn.addEventListener('click', function(){
// 1.location.assign:记录浏览历史,可以实现后退功能
// location.assign('https://blog.youkuaiyun.com/SevgiliD?type=blog');
//2.ocation.replace:不记录浏览历史,所以不能实现后退功能
location.replace('https://blog.youkuaiyun.com/SevgiliD?type=blog');
// 3.location.reload:重新加载页面
})
</script>
</body>
navigator对象
// 下面代码可判断用户用哪个终端打开页面,实现跳转(了解即可)
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对象
注:history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到