【干货分享|建议收藏】1w字搞定BOM

感激相遇 你好 我是阿ken

作者:请叫我阿ken
链接:请叫我阿ken主页链接
来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

🌊🌈关于前言:

文章部分内容及图片出自网络,如有问题请与我本人联系(主页介绍中有公众号)
本博客暂适用于刚刚接触 JS以及好久不看想要复习的小伙伴。

🌊🌈关于内容:

JavaScript BOM

8.1 BOM 简介

在实际开发中,使用 JavaScript 开发 Web 程序时,经常需要对浏览器进行访问及其他的操作,实现浏览器与页面之间的动态交互效果。为此,BOM 提供了很多用于访问浏览器的对象。本节将详细讲解 BOM 的组成。

8.1.1 什么是 BOM

浏览器对象模型 ( Brower Object Model, BOM ) 提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是 window。

BOM 由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。但是 BOM 缺乏标准,JavaScript 语法的标准化组织是 ECMA,DOM 的标准化组织是 W3C ,而 BOM 最初是 Netscape 网景浏览器标准的一部分。

8.1.2 BOM 与 DOM 的区别

DOM 是文档对象模型,把文档当作一个对象来看待, 它的顶级对象是 document,我们主要学习的是操作页面元素。DOM 是 W3C 标准规范。

BOM 是浏览器对象模型,是把浏览器当作一个对象来看待, 它的顶级对象是 window,我们主要学习的是浏览器窗口交互的一些对象。BOM 是浏览器厂商在各自浏览器上定义的,兼容性较差。

8.1.3 BOM 的构成

BOM 提供了很多的对象。这些对象用于访问浏览器,被称为浏览器对象。各内置对象之间按照某种层次组织起来的模型统称为浏览器对象模型,

BOM 的构成
在这里插入图片描述

从图中可以看出,BOM 比 DOM 更大,它包含 DOM ( doumemt ),BOM 的核心对象是 window ,其他的对象称为 window 的子对象,它们是以属性的方式添加到 window 对象中的。window 对象是浏览器顶级对象,具有双重角色,既是 JavaScript 访问浏览器窗口的一个接口,又是一个全局对象,定义在全局作用域中的变量、函数都会变成 window 对象的属性和方法。示例代码如下:

<script>

// 全局作用域中的变量是window对象的属性
var num = 10;
console.log (num);
// 结果为: 10
console.log (window.num);
// 结果为: 10
// 全局作用城中的函数是window对象的方法
function fn() {
console.log(11);
}
fn(); // 结果为: 11
window.fn();// 结果为: 11

</script>

在前面的知识中,之所以省略 var 也可以直接为一个未声明的变量赋值,是因为这个变量自动转换为了 window 对象的属性。前面学习的 alert()、 prompt() 实际上都属于 window 对象的方法,在调用的时候省略了前面的 " window. " 。 由于 window 对象中本来就有一个 name 属性,所以在全局作用域下声明的变量不推荐使用 name 作为变量名,以避免和 window 对象的 name 属性冲突。

8.2 window 对象的常见事件

8.2.1 窗口加载事件

1. window onload

window.onload 是窗口(页面)加载事件,当文档内容 (包括图像,脚本文件、CSS 文件等) 完全加载完成会触发该事件,调用该事件对应的事件处理函数。

JavaScript 代码是从上往下依次执行的,如果要在页面加载完成后执行某些代码,又想要把这些代码写到页面任意的地方,可以把代码写到 window.onload 事件处理函数中。因为 onload 事件是等页面内容全部加载完再去执行处理函数的。

onload 页面加载事件有两种注册方式,分别如下:

// 方式1
window.onload = function() { };

// 方式2
window.addEventListener('load', function () {  } );

需要注意的是,window.onload 注册事件的方式只能写一次,如果有多个,会以最后一个 window.onload 为准。如果使用 addEventListener 则没有限制。

2. document.DOMContentLoaded

doument.DOMContentloaded 加载事件会在 DOM 加载完成时触发。这里所说的加载不包括 CSS 样式表、图片和 flash 动画等额外内容的加载,因此,该事件的优点在于执行的时机更快,适用于页面中图片很多的情况。当页面图片很多时,从用户访问到 onload 事件触发可能需要较长的时间,交互效果就不能实现,这样会影响到用户的体验效果,在这时使用 document.DOMContentLoaded 事件更为合适,只要 DOM 元素加载完即可执行。

需要注意的是,该事件有兼容性问题,IE9以上才支持。

8.2.2 调整窗口大小事件 ( window.onresize 事件 )

当调整 window 窗口大小的时候,就会触发 window.onresize 事件,调用事件处理函数。该事件有两种注册方式,如下所示:

// 方式1
window.onresize = function() {  };

// 方式2
window.addEventListener('resize', function() {  } );

案例:演示利用页面加载事件和调整窗口大小事件完成响应式布局、示例代码如下:

<body>
<script>

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';
}
});
});

</script>

<div style="width: 200px; height: 100px; background-color: pink;">
</div>

</body>

在这里插入图片描述

上述代码中,绑定了 resize 调整窗口大小事件。
根据 if 条件语句进行判断,使用 window.innerWidth 获取当前屏幕的宽度,当屏幕小于等于 800 时隐藏 div 元素,否则显示该元素。

8.3 定时器

8.3.1 定时器方法

在浏览网页的过程中,我们经常可以看到轮播图效果,
即每隔一段时间,图片就会自动切换一次;或者在商品页面看到商品倒计时功能,这些动画就用到定时器。

定时器就是在指定时间后执行特定操作,或者让程序代码每隔一段时间执行一次,实现间歇操作。

在 JavaScript 中,提供了两组方法用于定时器的实现,

定时器方法

方法说明
setTimeout()在指定的毫秒数后调用函数或执行一段代码
setInterval()按照指定的周期(以毫秒计)来调用函数成执行一段代码
clearTimeout()取消由 setTimeout() 方法设置的定时器
clearlnterval()取消由 setInterval() 设置的定时器

上述表中,setTimeout() 和 setInterval() 方法都可以在一个固定时间段内执行代码,不同的是前者只执行一次代码,而后者会在指定的时间后自动重复执行代码。

在实际开发中,我们可以通过 setTimeout() 方法实现函数的一次调用,并且可以通过 clearTimeout() 来清除 setTimeout() 定时器。

setTimeout() 和 setInterval() 的语法格式如下:

setTimeout(调用的函数,[延迟的毫秒数])
setInterval(调用的函数,[延迟的毫秒数])

在上述语法中,第 1 个参数表示到达第 2 个参数设置的等待时间后要执行的代码,也可以传入一个函数,或者函数名,第 2 个参数的时间单位以毫秒 (ms) 计。

案例:以 setTimeout() 为例进行代码演示,

// 参数形式1: 用字符串表示一段代码
setTimeout('alert("JavaScript");', 3000);

// 参数形式2: 传入一个匿名函数
setTimeout(function() {
alert('JavaScript');
}, 3000);

// 参数形式3: 传入函数名
setTimeout(fn, 3000);
function fn() {
console.log('JavaScript');
}

在上述代码中,当参数为一个函数名时,这个函数名不需要加 () 小括号,否则就变成立即执行这个函数,将函数执行后的返回值传入。如果延迟的毫秒数省略时,默认为0。

在实际开发中,考虑到一个网页中可能会有很多个定时器,所以建议用一个变量保存定时器的id(唯一标识)。若想要在定时器启动后,取消该定时器操作,可以将 setTimeout() 的返回值(定时器id)传递给 clearTimeout() 方法。

// 在设置定时器时,保存定时器的唯一标识
var timer = setTimeout(fn, 3000);

// 如果要取消定时器,可将唯一标识传递给 clearTimeout() 方法
clearTimeout(timer);

8.3.2 [ 案例 ] 3 秒后自动关闭广告

本案例将会使用 setTimeout() 实现3秒后自动关闭广告的效果,具体代码如下:

<body>
<script>

console.log ('广告显示');
var timer = setTimeout(fn, 3000);
function fn() {
console.log('广告关闭了');
}

</script>
</body>

在这里插入图片描述

上述代码中,代码定义了一个 timer 变量用于保存setTimeout 定时器,定时器的功能为 3000ms 后执行 fn 函数。代码定义处理函数 fn,并打印 " 广告关闭了 "。

8.3.3 [案例] 60秒内只能发送一次短信

本案例将会利用 setInterval() 和 clearInterval() 方法完成一个发送短信的案例,要求60秒内只能发送一次短信。 其开发思路为,在页面中放一个文本框和一个 " 发送 " 按钮,在文本框中输人手机号码,然后单击 " 发送 " 按钮,就可以发送短信,但是短信发送后,该按钮在 60 秒以内不能再次点击,防止重复发送请求短信。并且在按钮单击之后,按钮上的文字会变为 " 还剩x秒再次单击 " 。

具体代码如下:

<body>

手机号码: 
<input type="number"> <button>发送</button>

<script>
var btn = document.querySelector('button');
var time = 60; // 定义剩下的秒数
btn.addEventListener('click', function() {
btn.disabled = true;
var timer = setInterval (function() {
if(time == 0) {
clearInterval(timer);
btn.disabled = false;
btn.innerHTML = '发送';
} else {
btn.innerHTML = ' 还剩下 ' + time + '秒';
time--;
}
}, 1000);
} );

</script>
</body>

在这里插入图片描述

上述代码中,代码定义了剩下的秒数。给按钮绑定单击事件,按钮被单击之后在第7行将 disabled 属性设置为 true 可以禁用按钮。按钮里面的内容需要变化,所以在 else 中通过 innerHTML 修改按钮内容,并且在第 15 行设置 time 变量不断递减。如果 time 为 0,执行 if 语句,停止定时器,复原按钮初始状态。

  • 多学一招: this指向问题
    _
    this 的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定 this 到底指向谁。一般情况下 this 的最终指向的是调用它的对象。为了使读者更好地理解,下面我们通过3个具体的场景来讲解 this 的指向问题。

  • (1) 在全局作用域或者普通函数中,this 指向全局对象window。示例代码如下:

console.log(this); // this指向的是window

function fn() {
console.log (this);
}

window.fn();
// this 指向的是window

在定时器方法的第 1 个参数的函数中,this 指向的也是 window 对象。

  • (2) 在方法中,谁调用的方法,this 就指向谁。示例代码如下:
var o = {

sayHi: function() {
console.log(this);
}

};
o.sayHi(); // sayHi中的this指向的就是o这个对象
  • (3) 构造函数中的 this 指向的是新创建的实例。示例代码如下:
function Fun() {
console.log(this);
}

var fun = new Fun();
// Fun中的this指向的是新创建的实例,即fun

8.4 JavaScript 执行机制

JavaScript 的定时器可以完成一些异步操作。例如,同时设置多个定时器,每个定时器都在3秒后执行一段代码,则三秒后,这些定时器中的代码都会执行。JavaScript 的定时器虽然没有 Java 中的多线程那样强大,但在开发中也能满足大部分的需求。

本节将针对 JavaScript 的执行机制进行讲解

8.4.1 单线程

JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。 这是因为 JavaScript 这门脚本语言诞生的使命所致,即 JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如,对某个 DOM 元素进行添加和删除操作,不能同时进行,应该先进行添加,之后再删除。

单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务, 这样所导致的问题是,如果 Javascript 执行的时间过长,就会造成页面的渲染不连贯,导致页面渲染加载有阻塞的感觉。

案例:演示,

console.log(1);

setTimeout(function() {
console.log(3);
}, 5000);

console.log(2);

执行上述代码,在控制台会看到程序先输出了1、2,等待 5 秒后输出 3。由此可见,当调用setTimeout() 方法后,该方法会立即执行完成,然后执行后面的代码,在控制台中输出 2。而为 setTimeout() 传入的函数,它会在 5 秒后执行。像这样的操作就称为异步操作。这个异步执行的函数称为回调函数,它的调用时机是由定时器来决定的。

8.4.2 同步和异步

为了更好地利用多核 CPU 的计算能力,HTML5 提出 Web Worker 标准,允许 JavaScript 脚本创建多个线程。于是 JavaScript 出现了同步和异步的概念。

  • 所谓同步,就是前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步做法,烧水煮饭,等水开了之后,再去切菜,炒菜。

  • 所谓异步,就是在做一件事件的同时, 可以去处理其他的事情。还以做饭为例,异步做法是,在烧水煮饭的同时去切菜炒菜。

同步任务都是在主线程上执行的,会形成一个执行栈, 而异步任务是通过回调函数实现的,一般来说,异步任务有 3 种类型, 第 1 种是普通事件,如 click、resize 等;第 2 种是资源加载,如 load、error 等;第 3 种是定时器,如 setlnterval()、setTimeout()。

8.4.3 执行机制

当定时器的时间设为 0 的时候,就会产生一个问题,到底是为定时器传入的回调周函数优先执行, 还是 setTimeout() 后面的代码优先执行呢?

示例代码如下:

console.log(1);

setTimeout(function() {

console.log(3);
}, 0);

for(var i = 0, str = ''; i < 900000; i++) {
str += i;
// 利用字符串拼接运算拖慢执行时间
}

console.log(2);

上述代码执行后, 输出顺序为1、2、3。显然, 为定时器传入的回调函数是最后执行的。为了降低偶然性,第 5 ~ 7 行的代码拖慢了执行时间,但最终结果仍然是 3 最后输出。

在 JavaScript 中,同步任务是优先执行的,它们会被放入执行栈中执行,而异步任务(回调函数)则被放人任务队列中,一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务就会结束等待状态,进人执行栈,开始执行。

因为 JavaScript 的主线程会不断地重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( Event Loop)。

8.5 location 对象

location 对象比较特别,它既是 window 对象的属性,同时也是 document 对象的属性,window location 等同于document.location,它们是引用了同一个对象。location 对象不仅提供了与当前显示文档相关的信息,而且还提供了用户获取和设置窗体的 URL。

8.5.1 URL 的组成

location 对象与 URL 相关,因此在学习 location 对象前,我们先来看一下 URL 的组成。在 Internet 上访问的每一个网页文件,都有一个访问标记符, 用于唯一标识它的访问位置,以便浏览器可以访问到,这个访问标记符称为统一资源定位符 ( Unifom Resoure Loator, URL)。

在 URL 中,包含了网络协议、服务器的主机名、端口号、资源名称字符串、参数以及锚点,具体示例如下:

// 示例1
protocol://host[:port]/path/[?query]fragment

// 示例2
http://www.example.com:80/web/index.html?a=3&b=4#res

URL 组成说明

各部分说明
protocol网络协议,常用的如 http、ftp、mailto 等
host服务器的主机名,如 www.example.com
port端口号,可选,省略时使用协议的默认端口,如 http 默认端口为 80
path路轻,如 " /web/index.html "
query参数为键值对的形式,通过 " & " 符导分隔,如 " a=3&b=4 "
fragment锚点,如 " #res " ,表示页面内部的锚点

8.5.2 location 的常用属性

BOM 中 location 对象提供的方法,可以更改当前用户在浏览器中访问的 URL ,实现新文档的载入、重载以及替换等功能。

location 对象提供的 search 属性返回 URL 中的参数,通常用于在向服务器查询信息时传入一些查询条件,如页码,搜索的关键字、排序方式等。除了 search 属性外,location 对象还提供了其他的属性,用于获取或设置对应的 URL 地址的组成部分,如服务器主机名、端口号、URL 协议以及完整的 URL 地址等。

location 对象的属性

属性说明
location.search返回(或设置)当前 URL 的查询部分( " ? " 之后的部分)
location.hash返回一个 URL 的锚部分( 从 " # " 开始的部分)
location.host返回一个 URL 的主机名和端口
location.hostname返回 URL 的主机名
location.href返回完整的 URL
location.pathname返回 URL 的路径名
location.port返回一个 URL 服务器使用的端口号
location.protocol返回一个 URL 协议

8.5.3 [ 案例 ] 获取 URL 参数

在实现登录功能时。需要在登录页面( login.html )进行表单提交。如果用户输入正确,则提交到 index.html 首页,并且需要把输人的用户名传递过去,这样首页中就可以获取并使用该用户名。了解了产品需求之后,接下来我们开始编写业务逻辑代码。

  • (1) 创建 login.html 登录页面,搭建表单结构,示例代码如下:
<form actlon="index html">
用户名: 
<input type="text" name="uname">
<input type="submit" value="登录">
</form>

上述代码中,使用 action 属性把表单提交到 index.html 页面。第4行 input 表单元素 type 属性设置为 " submit " ,表示当单击 " 登录 " 按钮时,表单自动提交。

  • (2) 创建 index.html 首页,示例代码如下:
<body>

<div></div>
<!-- div 元素用于展示从 login.html 页面传递过来的参数。-->

<script>
console.log (location, search);
// 结果为: ?uname=andy
// 使用 location.search 返回 URL 地址中的参数。

// 1.去掉search中的问号"?"
var params = location.search.substr(1);
console.log (params);
// 结果为: uname=andy
// 用来去掉字符串中第1个字符,也就是把参数字符串最前面的问号“?"去掉。

// 2.把字符串分割为数组
var arr = params.split('=');
console.log (arr);
// 结果为: ["uname", "andy"]
var div = document.querySelector('div');
// 利用 split() 方法把字符串分隔成数组。

// 3.把数据写人div中
div.innerHTML = arr[i] + '欢迎您';
// 为使用 innerHTML 把数据写人 div 中。
</script>

</body>

8.5.4 location 的常用方法

location 对象提供的用于改变 URL 地址的方法,所有主流的浏览器都支持,

location 对象的方法

方法说明
assign()载人一个新的文档
reload()重新加载当前文档
replace()用新的文档替换当前文档,覆盖浏览器当前记录

在上述表中,assign() 方法是比较常用的方式,使用 location.assign() 就可以立即打开一个新的浏览器位置,并生成一条新的历史记录。接收的参数为 URL 地址。

reload() 方法的唯一参数, 是一个布尔类型值,将其设置为 true 时,它会绕过缓存,从服务器上重新下载该文档,类似于浏览器中的 " 刷新页面 " 按钮。

replace() 方法的作用就是使浏览器位置发生改变,并且禁止在浏览器历史记录中生成新的记录,它只接受一个要导航到的 URL 参数,而且在调用 replace() 方法后,用户不能返回到前一个页面。

8.6 navigator 对象

navigator 对象包含有关浏览器的信息,但是每个浏览器中的 navigator 对象中都有一套自己的属性和方法,

navigator 对象的属性和方法

分类名称说明
属性appCodeName返回浏览器的内部名称
属性appName返回浏览器览器的完整名称
属性appVersion返回浏览器的平台和版本信息
属性cookieEnabled返回指明浏览器中是否启用 Conkie 的布尔值
属性platform返回运行浏览器的操作系统平台
属性userAgent返回由客户端发送到服务器的 User-Agent 头部的值
方法javaEnabled()指定是否在浏览器中启用 Java

在上表中,最常用的属性是 userAgent,

案例:演示 userAgent 的使用,

<script>
var msg = window.navigator.userAgent;
console.log (msg);
</script>

上述代码中,使用 window.navigator 来返回不同容户端发送到服务器的 Uset-Agent 头部的值。以 Chorme. Firefox、IE 浏览器为例,输人结果如下。

  • ( 1 ) Chrome
Mozilla/5.0 (windows NT 6.1; win64; x64) AppleWebkit/537.36 (KHTML, like Gecko)Chrome/77.0.3865.75 Safari/537.36

(2) Firefox

Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:69.0) Gecko/20100101 Firefox/69.0
  • ( 3 ) IE
Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2;.NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0;.NET4.0C; .NET4.0E; InfoPath.3)

8.7 history 对象

BOM 中提供的 history 对象,可以对用户在浏览器中访问过的 URL 历史记录进行操作。出于安全方面的考虑,history 对象不能直接获取用户浏览过的 URL ,但可以控制浏览器实现 " 后退 " 和 " 前进 " 的功能。

history 对象的属性和方法

分类名称说明
属性length返回历史列表中的网址数
方法back()加载 history 列表中的前一个 URL
方法forward()加载 history 列表中的下一个 URL
方法go()加载 history 列表中的某个具体页面

go() 方法可根据参数的不同设置,完成历史记录的任意跳转。当参数值是一个负整数时,表示后退 " 后退 " 指定的页数;当参数值是一个正整数时,表示 " 前进 " 指定的页数。

今日入门学习暂时告一段落
Peace

🌊🌈往期回顾:

JavaScript学习:
挑战最短时间内带你入门 JavaScript(一)
挑战最短时间内带你入门 JavaScript(二)
挑战最短时间内带你入门 JavaScript(三)
挑战最短时间内带你入门 JavaScript(四)
【干货分享|建议收藏】2w字爆肝详解 JavaScript对象
【建议收藏|熬夜爆肝】万字文带你了解DOM,文末有彩蛋嗷!!!✨✨✨

HTML学习:
阿ken的HTML、CSS的学习笔记_HTML基础(笔记一)
阿ken的HTML、CSS的学习笔记_HTML 页面元素和属性(笔记二)
阿ken的HTML、CSS的学习笔记_文本样式属性(笔记三)
阿ken的HTML、CSS的学习笔记_CSS3选择器(笔记四)
阿ken的HTML、CSS的学习笔记_CSS盒子模型(笔记五)
阿ken的HTML、CSS的学习笔记_浮动与定位(笔记六)
阿ken的HTML、CSS的学习笔记_表单的应用(笔记七)
阿ken的HTML、CSS的学习笔记_多媒体技术(笔记八)
阿ken的HTML、CSS的学习笔记_CSS3高级应用(笔记九)

🌊🌈关于后记:

感谢阅读,希望能对你有所帮助 博文若有瑕疵请在评论区留言或在主页个人介绍中添加联系方式私聊我 感谢每一位小伙伴不吝赐教
原创不易,「点赞」+「关注」+「收藏」 谢谢支持❤

  • 145
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 124
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 124
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我阿ken

观众老爷要是看的开心还请支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值