JavaScript-BOM
Posted 我真的爱敲代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript-BOM相关的知识,希望对你有一定的参考价值。
文章目录
1. BOM概述
BOM(Brower Object Model):浏览器对象模型。核心对象是window,因为它提供了独立内容而与浏览器窗口进行交互
BOM和DOM区别
DOM | BOM |
---|---|
文档对象模型 | 浏览器对象模型 |
DOM 就是把「文档」当做一个「对象」来看待 | 把「浏览器」当做一个「对象」来看待 |
DOM 的顶级对象是 document | BOM的顶级对象是window |
DOM 主要学习的是操作页面元素 | BOM学习的是浏览器窗口交互的一些对象 |
DOM 是 W3C 标准规范 | BOM是浏览器厂商在各自浏览器上定义的,兼容性较差 |
BOM构成
BOM比DOM更大,它包含DOM
window 对象是浏览器的顶级对象,它具有双重角色。
- JS 访问浏览器窗口的一个接口。
- 一个全局对象。定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。
在调用的时候可以省略 window,前面学习的对话框都属于 window 对象方法,如 alert()、prompt() 等。
注意:window下的一个特殊属性 window.name
2. windows对象的常见事件
窗口加载事件
//推荐使用,事件监听的方式
window.onload = function(){} //新型写法,时间不用写在标签属性中,js代码做到了和标签的完全分离
或者
window.addEventListener("load",function(){}); //ES6之后出现,也推荐使用,但存在浏览器兼容的问题
window.onload 是窗口 (页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS 文件等), 就调用的处理函数。
注意:
- 有了 window.onload 就可以把 JS 代码写到页面元素的上方,因为 onload 是等页面内容全部加载完毕,再去执行处理函数。
- window.onload 传统注册事件方式 只能写一次,如果有多个,会以最后一个 window.onload 为准。
- 如果使用 addEventListener 则没有限制
document.addEventListener('DOMContentLoaded',function(){})
DOMContentLoaded 事件触发时,仅当DOM加载完成,不包括样式表,图片,flash等等。
IE9以上才支持
如果页面的图片很多的话, 从用户访问到onload触发可能需要较长的时间, 交互效果就不能实现,必然影响用户的体验,此时用 DOMContentLoaded 事件比较合适。
调整窗口大小事件
window.onresize = function(){}
window.addEventListener("resize",function(){});
window.onresize 是调整窗口大小加载事件, 当触发时就调用的处理函数。
注意:
- 只要窗口大小发生像素变化,就会触发这个事件。
- 经常利用这个事件完成响应式布局。 window.innerWidth 当前屏幕的宽度
3. 定时器函数
方法 | 说明 |
---|---|
setTimeout() | 在指定的毫秒数后调用函数或执行一段代码(只执行一次) |
setInterval() | 按照指定的周期(以毫秒计)来调用函数或执行一段代码,即每段时间执行一次(执行多次) |
clearTimeout() | 取消由setTimeout()方法设置的定时器 |
clearInterval() | 取消由setInterval()设置的定时器 |
注意:
- 所有方法前面有window. ,可以省略
- 因为定时器可能有很多,所以经常给定时器赋值一个标识符
- 延迟时间单位是毫秒,但可以省略,如果省略默认的话是0
// 形式1
setTimeout('alert("javascript");',2000) //2秒后弹出消息框
// 形式2:传入一个匿名函数
setTimeout(function() {
alert('Js')
},2000)
// 形式3:先定义好一个函数,把函数名用来传递(传递一个函数名)
// 建议第三种写法
// 前两种适合函数体简单,若函数体复杂,则第三种代码的可读性更好
function fn() {
console.log('2秒后显示')
}
var timer = setTimeout(fn,2000)
clearTimeout(timer) //清除定时器对象
【案例】60s内只能发送一次短信
思路:
- 在页面中放一个文本框个一个“发送”按钮
- 在文本框中输入手机号码,然后点击“发送”按钮,就可以发送
- 在按钮单击之后,按钮上的文字会变味“还剩x秒再次单击”
<body>
手机号码:
<input type="number" name="" id="">
<button>发送</button>
<script>
// 1.选中按钮
var btn = document.querySelector('button') //使用标签名选择器
// 2.定义倒计时时间
var time = 60
// 3.给按钮注册事件监听
btn.addEventListener('click',function() {
// (1) 设置按钮状态
btn.disabled = true //按钮不可用状态
// (2)创建一个定时器
var timer = setInterval(function() {
if(time == 0) { //倒计时结束
clearTimeout(timer) //清除定时器
btn.disabled = false //按钮可用
btn.innerhtml = '发送' //修改按钮上的文字
time = 60 //可以实现多次点击发送,这个60需要重新开始
}else { //倒计时没有结束
btn.innerHTML = '还剩'+time+'秒' //设置按钮上显示的文字
time--
}
},1000)
})
</script>
</body>
this
this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下this的最终指向的是那个调用它的对象
几个this指向:
- 全局作用域或者普通函数中this指向全局对象window(注意定时器里面的this指向window,因为定时前通常省略了window.)
- 方法调用中谁调用this指向谁
- 构造函数中this指向构造函数的实例
4. JS执行队列
JS是单线程
JS语言的一大特点就是单线程,即同一时间只能做一件事情。
这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
- 进程:应用程序的一次动态运行(进程是动态的,应用程序是静态的)---->可以理解为进程就是程序,每个进程都有自己独立的内存空间
- 线程:为了提高CPU的利用效率,把一个进程分成若干个线程,由其去抢占CPU,线程就是进程的一个执行单位,线程无自己独立的内存空间
- 多线程的应用:手机抢红包(多线程,高并发)
console.log(1);
setTimeout(function () {
console.log(3);
}, 7000);
console.log(2);
运行结果:先输出1、2,等待5秒后输出3
同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
同步:
前一个任务结束后再执行后一个任务,程序的执行顺序和任务的排列顺序是一致的、同步的
JS执行机制(eg:烧水煮饭时,等谁开了之后(10分钟),再去切菜、炒菜)
异步:
在做一件事情的同时还可以去处理其他的事情。(eg:做饭的异步做法,在烧水的同时,利用这10分钟去切菜、炒菜)
本质区别:
这条流水线上各个流程的执行顺序不同。
同步任务:
同步任务都在主线程上进行,形成一个执行栈
异步任务:
JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型:
- 普通事件,如 click、resize 等
- 资源加载,如 load、error 等
- 定时器,包括 setInterval、setTimeout 等
异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)。
console.log(1);
setTimeout(function () {
console.log(3);
}, 0);
console.log(2);
运算结果还是 1 2 3
JS执行机制
- 先执行执行栈中的同步任务。
- 异步任务(回调函数)放入任务队列中。
- 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。
5. location对象
概述:
window 对象提供了一个== location 属性用于获取或设置窗体的 URL==,并且可以用于解析 URL 。 因为这个属性返回的是一个对象,所以将这个属性也称为 location 对象。
URL
统一资源定位符 (Uniform Resource Locator, URL) 是互联网上标准资源的地址。–>即网址
互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。
URL的一般语法格式:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
URL组成:
各部分 | 说明 |
---|---|
protocol | 网络/通信协议,常用的http,ftp,mailto等 |
host | 服务器的主机名(域名),如www.example.com等。本地机的ip地址是127.0.0.1,或localhost |
port | 端口号,可选,省略时使用方案的默认端口,如http的默认端口为80。一个服务器共有65535个端口,01023:通常由操作系统使用。102465535:用户使用,一般使用端口号较大的(http默认8080,mysql为3302),若自己使用8080,就不能浏览网页 |
path | 路径,由零或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址,如“users/index.html”---->访问users文件夹下的html文件 |
query | 参数,以键值对的形式,参数和参数之间通过&符号分隔开来,如“a=3&b=4”。参数和地址之间用?分隔。例如:http://localhost:8000/admin/findUser?name=‘张三’&password=‘123’ ,将来做前后台分离时,这样的地址经常会用到 |
fragment | 片段,#后面内容,常见于链接、锚点 |
location对象的属性
属性 | 说明/返回值 |
---|---|
location.search | 返回(或设置)参数,即当前URL的查询部分(“?”之后的部分) |
location.hash | 返回片段,#后面内容,即一个URL的锚部分,(从“#”开始的部分),常见于链接、锚点 |
location.host | 返回一个URL的主机名(域名)和端口 |
location.hostname | 返回URL的主机名 |
location.href | 返回(获取或设置)完整的URL |
location.port | 返回一个URL服务器使用的端口号,如果未写返回空字符串 |
location.pathname | 返回一个URL的路径名 |
location.protocol | 返回一个URL协议 |
location对象的方法
方法 | 说明/返回值 |
---|---|
location.assign() | 跟href一样,可以跳转页面(也称为重定向页面),载入一个新文档 |
location.reload() | 重新加载当前文档,相当于刷新按钮或者 f5 ,如果参数为true,强制刷新 ctrl+f5 |
location.replace() | 用新的文档替换当前文档,覆盖浏览器当前记录 页面,因为不记录历史,所以不能后退页面 |
【案例】5秒钟之后跳转页面
分析:
- 利用定时器做倒计时效果
- 时间到了,就跳转页面。使用location.href
<button>点击</button>
<div></div>
<script>
var btn = document.querySelector('button')
var div = document.querySelector('div')
btn.addEventListener('click', function () {
// console.log(location.href)
location.href = 'http://www.baidu.com'
})
var timer = 5
setInterval(function () {
if (timer == 0) {
location.href = 'http://www.baidu.com'
} else {
div.innerHTML = '您将在' + timer + '秒之后跳转到首页'
timer--
}
}, 1000)
</script>
【案例】获取URL参数数据
分析:
- 第一个登录页面,里面有提交表单, action 提交到 index.html页面
- 第二个页面,可以使用第一个页面的参数,这样实现了一个数据不同页面之间的传递效果
- 第二个页面之所以可以使用第一个页面的数据,是利用了URL 里面的 location.search参数
- 在第二个页面中,需要把这个参数提取。
- 第一步去掉? 利用 substr
- 第二步 利用=号分割 键 和 值 split(‘=‘)
- 第一个数组就是键 第二个数组就是值
login.html页面代码:
<form action="index.html">
用户名:<input type="text" name="uname">
<input type="submit" value="登录">
</form>
index.html页面代码:
<div></div>
<script>
// console.log(location.search) //拿到的包括?uname= 要把它去掉
// 1、先去掉? substr('起始的位置',截取几个字符)
var params = location.search.substr(1) //拿到的包括uname=
// 2、利用=把字符串分割为数组 split('=')
var arr = params.split('=')
console.log(arr)
var div = document.querySelector('div')
// 3、把数据写入div中
div.innerHTML = arr[1] + '欢迎您'
</script>
6. 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端页面
}
7. history对象
window 对象给我们提供了一个 history 对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的 URL。
常用属性:
history.length:返回历史列表中的网址数
常用方法:
方法 | 说明 |
---|---|
back() | 后退功能,加载histroy列表中的前一个URL |
forward() | 前进功能,加载history列表中的下一个URL |
go(参数) | 前进后退功能,加载histroy列表中的某个具体页面,参数如果是1,前进1个页面,如果是-1,后退一个页面,若参数为n则为前进/后退n个页面 |
history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。
以上是关于JavaScript-BOM的主要内容,如果未能解决你的问题,请参考以下文章