Web APIs 学习流程
Web APIs学习流程 我都会在我的js专栏出。
- DOM的元素操作:**DOM-获取元素 **(获取元素、修改属性) + DOM-节点操作(节点的增删改查) + 事件(DOM0 弃用 了解)
- 事件:DOM-事件基础(注册事件、tab栏切换) + DOM-事件进阶(事件对象、事件委托)
- 操作浏览器:BOM-操作浏览器(BOM、插件、本地存储)
- 正则表达式+综合案例
1 BOM概述
window对象是浏览器的顶级对象
,它具有双重角色。
- 它是JS访问浏览器窗口的一个接口。
- 它是一个全局对象。定义在全局作用域中的变量、函数都会变成window对象的属性和方法。
在调用的时候可以省略window,前面学习的对话框都属于window对象方法,如alert()、prompt()等。
注意:window下的一个特殊属性window.name
2 windown 对象的常见事件
请看我的 js专栏的 JavaScript之事件 的博客的 常见事件名
事件名 | 说明 |
---|---|
元素.addEventListener(‘load’ , ()=>{ }) | 页面加载事件第八章BOM |
元素.addEventListener(‘DOMContentLoaded’ , ()=>{ }) | 页面加载事件第八章BOM |
元素.addEventListener(‘scroll’ , ()=>{ }) | 滚动条在滚动时 持续触发的事件 |
window.addEventListener(‘resize’ , ()=>{ }) | 会在窗口尺寸改变时 触发事件 |
window.setInterval(回调函数,延迟毫秒数) | 设置循环定时器 window可省略 |
window.clearInterval(回调函数,延迟毫秒数) | 清除循环定时器 window可省略 |
window.setTimeout(回调函数,延迟毫秒数) | 设置一次性定时器 window可省略 |
window.clearTimeout(回调函数,延迟毫秒数) | 清除一次性定时器 window可省略 |
2 页面事件
2.1 页面加载事件
2.1.1 语法
window.onload=function(){}
// 或者
window.addEventListener("load",function(){});
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等),就调用的处理函数
注意:
- 有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数。
- window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。
- 如果使用addEventListener则没有限制
document.addEventListener('DoMcontentLoaded',function(){});
DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。 le9以上才支持
注意:如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用DoMContentLoaded事件比较合适。
2.1.2 语法总结
- load
- 语法
window.addEventListener('load' , ()=>{ })
window可省略 传统写法是加on - 作用:加载外部资源(如图片、外联CSS和JavaScript等)加载完毕时触发的事件
- 注意:监听页面所有资源加载完毕 给 window 添加 load 事件
- 语法
- DOMContentLoaded
- 语法
window.addEventListener('DOMContentLoaded' , ()=>{ })
window可省略 传统写法是加on - 当初始的
HTML 文档(dom元素也就是标签)
被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表、图像等完全加载 - 注意:监听页面DOM加载完毕:给 document 添加 DOMContentLoaded 事件
- 语法
2.1.3案例
-
下面代码报错是因为 页面从上往下加载 边编译边执行
<html lang="en"> <head> <title>Document</title> <script> // 报错 Uncaught TypeError: Cannot read properties of null (reading 'addEventListener') // 下面代码报错是因为 页面从上往下加载 边编译边执行 当执行此处找不到<button>点击</button> // 这就是因为为什么 我们之前js代码放在 所有元素下面 const btn = document.querySelector('button') btn.addEventListener('click', function () { alert(11) }) // img.addEventListener('load', function () { // // 若图片比较大 用这个事件 等待图片加载完毕,再去执行里面的代码 // }) </script> </head> <body> <button>点击</button> </body> </html>
-
我们如何做到让js写在上面呢 这就需要我们所学的load了
<html lang="en"> <head> <title>Document</title> <script> // 等待页面所有资源加载完毕,就回去执行回调函数 window.addEventListener('load', function () { const btn = document.querySelector('button') btn.addEventListener('click', function () { alert(11) }) }) </script> </head> <body> <button>点击</button> </body> </html>
-
DOMContentLoaded
<html lang="en"> <head> <title>Document</title> <script> // 等待页面DOM元素(标签)加载完毕,就回去执行回调函数 document.addEventListener('DOMContentLoaded', function () { const btn = document.querySelector('button') btn.addEventListener('click', function () { alert(11) }) }) </script> </head> <body> <button>点击</button> </body> </html>
注意
load 等页面内容全部加载完毕,包含页面dom元素 图片 flash css 等等
DOMContentLoaded 是DOM 加载完毕,不包含图片 falsh css 等就可以执行 加载速度比 load更快一些
2.2 页面滚动事件
scroll事件作用范围
给window或者document加滚动 他们效果一样
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>页面滚动</title>
<style>
body{
height: 1000px;
}
div {
/* display: none; */
margin: 100px;
overflow: scroll;
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div>
晨曦初破,山林从沉睡中渐渐苏醒。日光如细碎的金箔,穿过枝叶的缝隙,洒下一地斑驳。
踏入山林,首先映入眼帘的是那片翠绿的竹海。修长的翠竹高耸入云,微风拂过,竹叶沙沙作响,似在低声诉说着昨夜的梦境。露珠在竹叶上滚动,宛如晶莹的珍珠,折射出五彩的光芒。
沿着蜿蜒的小径前行,便能听到潺潺的流水声。一条清澈见底的小溪欢快地流淌着,水底的石头和沙砾清晰可见。溪水时而湍急,时而平缓,撞击在石头上,溅起层层洁白的水花,宛如盛开的白莲。溪边生长着各种不知名的野花,红的、黄的、紫的,争奇斗艳,为这清幽的山林增添了一抹亮丽的色彩。
抬头仰望,天空湛蓝如宝石,几缕白云悠然飘荡,仿佛是大自然随手挥洒的水墨。鸟儿在枝头欢唱,歌声清脆悦耳,此起彼伏,与风声、水声交织在一起,构成了一曲美妙的自然交响乐。
此时的山林,充满了生机与活力。每一处景色,每一种声音,都让人感受到大自然的神奇与魅力,仿佛置身于一幅绝美的画卷之中,令人陶醉,流连忘返。
</div>
<script>
window.addEventListener("scroll",()=>{
console.log("window");
})
document.addEventListener("scroll",()=>{
console.log("document");
})
document.querySelector('div').addEventListener("scroll",()=>{
console.log("div");
})
</script>
</body>
</html>
元素的scrollLeft和scrollTop(属性)
语法 元素.scrollTop
- 获取被卷去的大小
- 获取元素内容往左、往上滚出去看不到的距离
- 这两个值是可读写的 这里的修改值是数字不带px 元素.scrollTop = 800 不带px
- 必须写在scroll事件里面获取被卷去的距离
下面是使用元素的scrollTop属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>元素的scrollTop属性</title>
<style>
div {
margin: 200px;
overflow: scroll;
width: 200px;
height: 200px;
border: 1px solid #000;
}
</style>
</head>
<body>
<div>
晨曦初破,山林从沉睡中渐渐苏醒。日光如细碎的金箔,穿过枝叶的缝隙,洒下一地斑驳。
踏入山林,首先映入眼帘的是那片翠绿的竹海。修长的翠竹高耸入云,微风拂过,竹叶沙沙作响,似在低声诉说着昨夜的梦境。露珠在竹叶上滚动,宛如晶莹的珍珠,折射出五彩的光芒。
沿着蜿蜒的小径前行,便能听到潺潺的流水声。一条清澈见底的小溪欢快地流淌着,水底的石头和沙砾清晰可见。溪水时而湍急,时而平缓,撞击在石头上,溅起层层洁白的水花,宛如盛开的白莲。溪边生长着各种不知名的野花,红的、黄的、紫的,争奇斗艳,为这清幽的山林增添了一抹亮丽的色彩。
抬头仰望,天空湛蓝如宝石,几缕白云悠然飘荡,仿佛是大自然随手挥洒的水墨。鸟儿在枝头欢唱,歌声清脆悦耳,此起彼伏,与风声、水声交织在一起,构成了一曲美妙的自然交响乐。
此时的山林,充满了生机与活力。每一处景色,每一种声音,都让人感受到大自然的神奇与魅力,仿佛置身于一幅绝美的画卷之中,令人陶醉,流连忘返。
</div>
<script>
let div = document.querySelector('div')
div.addEventListener("scroll",()=>{
console.log(div.scrollTop);
})
</script>
</body>
</html>
下面是使用html页面的scrollTop属性
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
body{
height: 1000px;
}
</style>
</head>
<body>
<script>
window.addEventListener("scroll",()=>{
// console.log(document.scrollTop); //document 没有scrollTop属性undefined
// 这是为什么呢,我们打印一下 document发现他是存放了
// 地址+<!DOCTYPE html><html lang="en">...</html>
// console.log(document);
// 所以我们需要获取 html标签才能得到页面的scrollTop
// console.log(document.documentElement);//<html lang="en">...</html>
// 扩展:如果获取body呢
// console.log(document.body);//<body>...</body>
console.log(document.documentElement.scrollTop)// 变化
// console.log(document.body.scrollTop)//一直是0
})
</script>
</body>
</html>
元素的scrollTo()方法
2.3 调整窗口大小事件
<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);
console.log('变化了');
if (window.innerWidth <= 800) {
div.style.display = 'none';
} else {
div.style.display = 'block';
}
})
})
</script>
<div></div>
3 定时器
事件名 | 说明 |
---|---|
window.setInterval(回调函数,延迟毫秒数) | 设置循环定时器 window可省略 |
window.clearInterval(回调函数,延迟毫秒数) | 清除循环定时器 window可省略 |
window.setTimeout(回调函数,延迟毫秒数) | 设置一次性定时器 window可省略 |
window.clearTimeout(回调函数,延迟毫秒数) | 清除一次性定时器 window可省略 |
3.1 定时器之setTimeout
<script>
// 1. setTimeout
// 语法规范: window.setTimeout(调用函数, 延时时间);
// 1. 这个window在调用的时候可以省略
// 2. 这个延时时间单位是毫秒 但是可以省略,如果省略默认的是0
// 3. 这个调用函数可以直接写函数 还可以写 函数名 还有一个写法 '函数名()'
// 4. 页面中可能有很多的定时器,我们经常给定时器加标识符 (名字)
//写法一
// setTimeout(function() {
// console.log('时间到了');
// }, 2000);
//写法二
function callback() {
console.log('爆炸了');
}
var timer1 = setTimeout(callback, 3000);//多个定时器用var 变量 = setTimeout()
var timer2 = setTimeout(callback, 5000);
//写法三
// setTimeout( ()=>{ }, 3000);
</script>
3.2 清除定时器 clearTimeout
<button>点击停止定时器</button>
<script>
var btn = document.querySelector('button');
var timer = setTimeout(function() {
console.log('爆炸了');
}, 5000);
btn.addEventListener('click', function() {
clearTimeout(timer);
})
</script>
3.3 定时器之setInterval
<script>
// 1. setInterval
// 语法规范: window.setInterval(调用函数, 延时时间);
setInterval(function() {
console.log('继续输出');
}, 1000);
// 2. setTimeout 延时时间到了,就去调用这个回调函数,只调用一次 就结束了这个定时器
// 3. setInterval 每隔这个延时时间,就去调用这个回调函数,会调用很多次,重复调用这个函数
</script>
3.4 清除定时器 clearInterval
<button class="begin">开启定时器</button>
<button class="stop">停止定时器</button>
<script>
var begin = document.querySelector('.begin');
var stop = document.querySelector('.stop');
var timer = null; // 全局变量 null是一个空对象
begin.addEventListener('click', function() {
timer = setInterval(function() {
console.log('ni hao ma');
}, 1000);
})
stop.addEventListener('click', function() {
clearInterval(timer);
})
</script>
3.5 两种定时器区别
-
setInterval
只执行一次回调函数。一旦到达指定的延迟,回调函数就会被调用,之后定时器就结束了,不会重复调用。
用法:适用于需要在一段时间后执行一次特定操作的场景,例如延迟加载资源、显示提示信息等。
-
setTimeout
会重复执行回调函数,每隔指定的时间间隔就会调用一次回调函数,直到使用
clearInterval()
手动清除定时器。用法:适用于需要定期执行某些任务的场景,例如轮播图切换、实时数据更新等。
let a = setTimeout(()=>{console.log(1);},1000)// 1秒后输出1,不再输出
let b = setInterval(()=>{console.log(2);},1000)//每个1秒输出一次2
3.6 定时器this指向问题
无论是箭头函数还是传统的函数的回调函数,定时器的this都指向window
let a = setTimeout(()=>{console.log(this);},1000)//Window
let b = setTimeout(function (){console.log(this);},1000)//Window
<button>点击</button>
<script>
// this 指向问题 一般情况下this的最终指向的是那个调用它的对象
// 1. 全局作用域或者普通函数中this指向全局对象window( 注意定时器里面的this指向window)
console.log(this);
function fn() {
console.log(this);
}
window.fn();
window.setTimeout(function() {
console.log(this);
}, 1000);
// 2. 方法调用中谁调用this指向谁
var o = {
sayHi: function() {
console.log(this); // this指向的是 o 这个对象
}
}
o.sayHi();
var btn = document.querySelector('button');
// btn.onclick = function() {
// console.log(this); // this指向的是btn这个按钮对象
// }
btn.addEventListener('click', function() {
console.log(this); // this指向的是btn这个按钮对象
})
// 3. 构造函数中this指向构造函数的实例
function Fun() {
console.log(this); // this 指向的是fun 实例对象
}
var fun = new Fun();
var btn = document.querySelector('button');
var time = 3; // 定义剩下的秒数
btn.addEventListener('click', function() {
btn.disabled = true;//可以改为this
var timer = setInterval(function() {
if (time == 0) {
// 清除定时器和复原按钮
clearInterval(timer);
btn.disabled = false;//不可以改为this 因为setInterval指向window
btn.innerHTML = '发送';
} else {
btn.innerHTML = '还剩下' + time + '秒';
time--;
}
}, 1000);
})
</script>
案例
- 5秒后自动关闭的广告
- 倒计时效果
- 发送短信
4 JS执行机制
4.1 js同步和异步
4.1JS是单线程
JavaScript语言的一大特点就是单线程
,也就是说,同一个时间只能做一件事
。这是因为Javascript这门脚本语言诞生的使命所致一一JavaScript是为处理页面中用户的交互,以及操作DOM而诞生的。比如我们对某个DOM元素进行添加和删除操作,不能同时进行。应该先进行添加,之后再删除。
单线程就意味看,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是:如果JS执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
为了解决这个问题,利用多核CPU的计算能力,HTML5提出WebWorker标准,允许JavaScript脚本创建多个线程。于是,JS中出现了同步
和异步
。
同步
前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排例顺序是一致的、同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。
异步
你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。
他们的本质区别:这条流水线上各个流程的执行顺序不同
<script>
//第一个问题
console.log(1);
setTimeout(function() {
console.log(3);
}, 1000);
console.log(2);
// 2. 第二个问题
// console.log(1);
// setTimeout(function() {
// console.log(3);
// }, 0);
// console.log(2);
// 3. 第三个问题
// console.log(1);
// document.onclick = function() {
// console.log('click');
// }
// console.log(2);
// setTimeout(function() {
// console.log(3)
// }, 3000)
</script>
4.2 同步任务和异步任务执行过程
同步任务
同步任务都在主线程上执行,形成一个执行栈
异步任务
JS的异步是通过回调函数实现的
一般而言,异步任务有以下三种类型
- 普通事件,如click、resize等
- 资源加载,如load、error等
- 定时器,包括setlnterval、setTimeout等
异步任务相关回调函数
添加到任务队列
中(任务队列也称为消息队列)。
<script>
// 第一个问题
// console.log(1);
// setTimeout(function() {
// console.log(3);
// }, 1000);
// console.log(2);
//2. 第二个问题
console.log(1);
setTimeout(function() {
console.log(3);
}, 0);
console.log(2);
// 3. 第三个问题
// console.log(1);
// document.onclick = function() {
// console.log('click');
// }
// console.log(2);
// setTimeout(function() {
// console.log(3)
// }, 3000)
</script>
4.3 js执行机制
- 先执行
执行栈中的同步任务
。 - 异步任务(回调函数)放入
任务队列
中。 - 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(eventloop)
。如下图
<script>
// 第一个问题
// console.log(1);
// setTimeout(function() {
// console.log(3);
// }, 1000);
// console.log(2);
//2. 第二个问题
// console.log(1);
// setTimeout(function() {
// console.log(3);
// }, 0);
// console.log(2);
// 3. 第三个问题
console.log(1);
document.onclick = function() {
console.log('click');
}
console.log(2);
setTimeout(function() {
console.log(3)
}, 3000)
</script>
5 location 对象
5.1 location对象常见属性
什么是location对象
window对象给我们提供了一个location属性
用于获取或设置窗体的URL
,并且可以用于解析URL
。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象
。
URL
统一资源定位符(UniformResourceLocator,URL)
是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它
# URL的一般语法格式为:
protocol://host[:port]/path/ [?query]#fragment
http: //www.itcast.cn/index.html?name=andy&age=18#link
组成 | 说明 |
---|---|
protocol | 通信协议常用的http,ftp,maito等 |
host | 主机(域名)www.baidu.com |
port | 端口号可选,省略时使用方案的默认端口如http的默认端口为80 |
path | 路径由零或多个/符号隔开的字符串,一般用来表示主机上的一个目录或文件地址 |
query | 参数以键值对的形式,通过&符号分隔开来 |
fragment | 片段#后面内容常见于链接锚点 |
location对象的属性
location对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个URL |
location.host | 返回主机 (域名)www.itheima.com |
location.port | 返回端口号如果未写返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 #后面内容 常见于链接 锚点 |
重点记忆:search和hash
5.2 案例 五秒之后转跳页面
先了解以下案例
<button>点击</button>
<script>
var btn = document.querySelector('button');
var div = document.querySelector('div');
btn.addEventListener('click', function() {
// console.log(location.href);
location.href = 'http://www.itcast.cn';//给这个属性直接跳转
})
</script>
<button>按钮</button>
<div></div>
<script>
var div = document.querySelector('div');
var btn = document.querySelector('button');
var number = 5;
btn.addEventListener('click',function(){
getCountDown();
setInterval(getCountDown, 1000);
});
function getCountDown(){
if(number == 0){
location.href = 'http://www.itcast.cn';
}else{
div.innerHTML = "还有" + number + "秒跳转页面";
number--;
}
}
</script>
5.3 获取URL参数
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<form action="index.html">
用户名: <input type="text" name="uname">
<input type="submit" value="登录">
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
</head>
<body>
<div></div>
<script>
console.log(location.search); // ?uname=andy
// 1.先去掉? substr('起始的位置',截取几个字符);
var params = location.search.substr(1); // uname=andy
console.log(params);
// 2. 利用=把字符串分割为数组 split('=');
var arr = params.split('=');
console.log(arr); // ["uname", "ANDY"]
var div = document.querySelector('div');
// 3.把数据写入div中
div.innerHTML = arr[1] + '欢迎您';
</script>
</body>
</html>
5.4 location常见方法
location对象的方法
location对象方法 | 返回值 |
---|---|
location.assign() | 跟href一样,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,因为不记录历史,所以不能后退页面 |
location.reload() | 重新加载页面,相当于刷新按钮或者f5如果参数为true强制刷新ctrl+f5 |
<button>点击</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
// 记录浏览历史,所以可以实现后退功能
// location.assign('http://www.itcast.cn');
// 不记录浏览历史,所以不可以实现后退功能
// location.replace('http://www.itcast.cn');
location.reload(true);
})
</script>
6 navigator 对象
navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值
下面前端代码可以判断用户那个终端打开页面,实现跳转
if ((navigator.userAgent.match(/(phone|pad|pod|iPhone |iPod| ios| iPad |Android |Mobile | BlackBerryl IEMobile | MQQBrowser | JUC | Fennec | wOSBrowser | BrowserNG | WebOSISymbian | Windows Phone)/ i)))
{
//手机
window.location.href = "";
} else {
window.location.href = "";
//电脑
}
7 history 对象
window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forwardo | 前进功能 |
go(参数) | 前进后退功能参数如果是1前进1个页面如果是-1后退1个页面 |
<a href="list.html">点击我去往列表页</a>
<button>前进</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
// history.forward();
history.go(1);
})
</script>
<a href="index.html">点击我去往首页</a>
<button>后退</button>
<script>
var btn = document.querySelector('button');
btn.addEventListener('click', function() {
// history.back();
history.go(-1);
})
</script>