JavaScript:BOM操作

JavaScript:BOM操作

    • BOM与JavaScript的关系
    • window对象
    • window对象的常用属性方法
      • 定时器
        • 间歇函数
        • 延时函数
      • JavaScript执行机制
        • 同步
        • 异步
        • 事件循环
      • location对象
      • navigator对象
      • histroy对象
      • 浏览器的本地存储
        • localStorage
        • sessionStorage
      • 复杂数据类型的存储
        • JSON字符串


BOM与JavaScript的关系

JavaScript的组成:

  • ECMAScript:

    • 规定了js基础语法核心知识。
    • 比如:变量、分支语句、循环语句、对象等等
  • Web APIs :

    • DOM 文档对象模型, 定义了一套操作HTML文档的API
    • BOM 浏览器对象模型,定义了一套操作浏览器窗口的API

JavaScript:BOM操作_第1张图片
也就是说,BOM是JavaScript的一个分支,其语法可以操控浏览器

window对象

BOM (Browser Object Model ) 是浏览器对象模型

  • window对象是一个全局对象,也可以说是JavaScript中的顶级对象
  • 像document、alert()、console.log()这些都是window的属性,基本BOM的属性和方法都是window的
  • 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法
  • window对象下的属性和方法调用的时候可以省略window
    JavaScript:BOM操作_第2张图片

解析一下上面的语句:

documentJavaScript中最常用的对象,因为其是文档树的根节点,其分支包含着所有HTML的元素。但是document并不是JavaScript中最高级的对象,而是windowwindow有多高级呢?
由于window是浏览器对象模型(BOM)的根节点,所以所有的对象都是window的后代节点,甚至你创建的变量,也会放在window对象里。
所以window作为一切的根,那么就可以默认存在,于是它就省略了。就好比你在填写地址的时候,绝对不会从地球开始:地球,中国,xx省…,因为人类都是默认处于地球环境中,所以我们会把地球省略。

也许你知道,var创建的变量是全局变量,letconst创建的变量是局部变量,这又是为什么?
这是因为,var创建的对象,会被直接放在window下面,与document同一级别,所以在DOM树中的任何一个节点往上找,都可以找到var定义的变量。
证明:
JavaScript:BOM操作_第3张图片
可以看到,我们用var创建的变量直接处于window对象下了,而letconst创建的变量没有。


window对象的常用属性方法

定时器

网页中经常会需要一种功能,比如每隔一段时间,就重复改变某些元素,比如倒计时;或者说某个操作过一段时间后,浏览器做出反应,比如广告x秒后自动关闭。
以上效果都离不开定时器的使用,JavaScript中的定时器最常用的有两种:间歇函数,延时函数。

间歇函数

间歇函数的功能是,每隔一段时间,就执行指定的代码。
语法:

setInerval(函数, 间隔时间)

第一个参数为函数,其用于承载每隔一段时间就要执行的代码;第二个参数为间隔时间,也就是每隔多久执行这个函数,间隔时间的单位是ms,其中:1s = 1000ms。

接下来我写一个倒计时案例:

        const div = document.querySelector("div");

        let i = 10;
        div.innerHTML = i;
        setInterval(() => {
            i--;
            div.innerHTML = i;
        }, 1000)

在页面中有一个盒子,我们想在其内部实现从10开始的倒计时:
我们先创建一个从10开始的变量,然后在设置一个间歇函数,时间间隔为1000即一秒,每次执行函数i–,并将盒子的内容改为i。

效果如下:


但是以上案例有一个问题,那就是当我们的i为负值的时候,我们的间歇函数不会停止。这就需要另外一个函数clearInterval来停止间歇函数的执行了:

语法:

clearInterval(变量名)

这里的变量名,是间歇函数的编号,那么什么是间歇函数的编号?
我们在调用间歇函数的时候,间歇函数会给出一个返回值,这个返回值是一个数字,是对这个间歇函数的编号:

示例:
JavaScript:BOM操作_第4张图片
在示例中,创建了三个间歇函数,并获取了它们的返回值,输出返回值到控制台发现,返回值就是简单的数字,也就是每个间歇函数的编号。clearInterval通过这个编号得知应该关闭哪一个计时器。

那么我们再优化一下倒计时的案例:

        let i = 10;
        div.innerHTML = i;
        const timer1 = setInterval(() => {
            i--;
            div.innerHTML = i;
            if (i === 0)
                clearInterval(timer1);
        }, 1000)

当i等于0时,就停止间歇函数执行下去,最后就会停在0处。
效果如下:


最后我们的倒计时就可以在0时刻停止了。


延时函数

延时函数,就是在触发某个事件后,延时一段事件再执行。
语法:

setTimeout(函数, 等待时间)

其两个参数与间歇函数是一致的,此处就不再详解了。

案例:
为网页设置一个开屏广告,并在5秒后自动关闭:

        const div = document.querySelector("div");

        setTimeout(() => {
            div.style.display = "none";
        }, 5000)

以上代码,设置了一个延时函数,并将其第二个参数设为5000即5秒。5秒后执行函数,将div的显示模式变为不显示,这样广告就消失了。

效果:

此外,延时函数也可以依靠代码停止,即clearTimeout
语法:

clearTimeout(变量名)

其用法与之前的间歇函数是一致的,此处就不过多讲解这个变量名是什么意思了。


JavaScript执行机制

讲完两个计时器,大家不妨看看下面这题:
请问一下代码的输出结果是什么:

console.log(111);

setTimeout(() => {
	console.log(222);
}, 1000);

console.log(333);

这题非常简单,当打开页面时,先从上到下输出111222,当延时函数的1s倒计时结束再输出333

那么以下代码的输出结果是什么:

console.log(111);

setTimeout(() => {
	console.log(222);
}, 0);

console.log(333);

依照正常逻辑,由于延时函数的倒计时为0s,相当于不存在。从上往下执行输出:111222333
可是实际并非如此,此代码的输出结果依然为111333222
这是JavaScript的执行机制导致的。

JavaScript语言的一大特点就是单线程,也就是说,同一时间只能做一件事情。
单线程就意味着,所有的任务需要排队,前一个任务结束,后一个任务才会开始执行,这就会导致一个问题:当前面的代码执行时间过长,迟迟没有响应,后面的任务被阻塞,就会使用户产生页面卡顿的感觉。
为了解决这个问题,利用多核CPU的计算能力,HTML5提出了Web Worker标准,允许JavaScript脚本创建多个线程,于是JavaScript出现了同步异步


同步

同步是指,当前一个任务结束,才执行后一个任务,程序执行的顺序是一致的,同步的

同步任务会在执行栈中按照顺序执行。

异步

异步是指,在执行某个任务的同时,程序还可以执行其他的任务

异步任务会在任务队列(消息队列)中等待,等到可以执行时,插入执行栈的末尾

一般而言,异步任务有以下类型:

普通事件,如cilckresize
资源加载,如loaderror
定时器,如setIntervalsetTimeout

事件循环

在同步与异步之间,存在着一个事件事件循环的交互关系,即:

当执行栈中的所有同步任务执行完毕,系统会每隔一段时间读取任务队列中的异步任务,如果异步任务可以执行了,就会结束等待状态,从任务队列进入到执行栈中,开始执行。

JavaScript:BOM操作_第5张图片
事件循环可以拆分为以下过程:

1.先执行执行栈中的同步任务
2.将异步任务放到任务队列中
3.执行栈执行完所有同步任务
4.每隔一段时间读取任务队列中的任务
5.如果任务队列中有可执行的任务,就放到执行栈中
6.回到步骤1,再次循环

由于这个过程是从1-6循环执行,所以这个过程也叫做事件循环。

我们看到一开始的问题,来帮助理解:

console.log(111);

setTimeout(() => {
	console.log(222);
}, 0);

console.log(333);

在这串代码中,有三个输出语句,其中111333是一般的语句,会放入执行栈中,而222语句被放在了定时器中,虽然定时器时间为0,但是不会立即执行,而是进入任务队列中等待

JavaScript:BOM操作_第6张图片
当任务被安排好:

执行执行栈中的任务:输出111333
读取任务队列中的任务console.log(222)到执行栈中
执行执行栈中的任务:输出222

所以这题是JavaScript的执行机制导致的问题,虽然console.log(222)console.log(333)的前面,但是由于其是定时器的特性,会进入任务队列,导致其执行顺序会晚于console.log(333)


location对象

location对象保存了当前页面的URL地址,并且可以根据方法来拆分不同的部分。
常用属性和方法:

属性/方法 说明
href 属性,获取完整的 URL 地址,赋值时用于地址的跳转
search 属性,获取地址中携带的参数,符号 ?后面部分
hash 属性,获取地址中的啥希值,符号 # 后面部分
reload() 方法,用来刷新当前页面,传入参数 true 时表示强制刷新

三个属性:
JavaScript:BOM操作_第7张图片
以CSDN主页为例,我们通过三个属性,分别输出了这个链接的不同部分,由于此链接没有哈希值,所以hash输出为空字符串。

此外,href属性是一个可读写属性,可以在JavaScript中修改当前得到href属性,实现页面的跳转。
reload()方法,则是一个强制刷新页面的方法,调用后,传入true参数,当前页面就会强制刷新。


navigator对象

navigator对象,其记录下了当前浏览器的相关信息,当某些浏览器不兼容你的网页时,可以通过这个对象的属性值来判断。
常用属性和方法:

  • 通过 userAgent 检测浏览器的版本及平台:
// 检测 userAgent(浏览器信息)
(function () {
  const userAgent = navigator.userAgent
  // 验证是否为Android或iPhone
  const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)
  const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)
  // 如果是Android或iPhone,则跳转至移动站点
  if (android || iphone) {
    location.href = 'http://m.itcast.cn'
  }})();

histroy对象

history对象其内部存储着浏览器的历史记录,并且可以实现页面的前进后退功能。

常见方法:

方法 作用
back() 后退
forward() 前进
go(参数) 可以前进和后退。如果参数为1就前进一个页面,如果为-1就后退一个页面

这个对象的使用已经很少了,因为大部分浏览器自带前进后退功能。


浏览器的本地存储

随着互联网的发展,网页的应用越来越广泛,也变得越来越复杂,为了满足需求,HTML5提供了本地存储的方案,来在本地存储大量数据。
通过浏览器本地存储的数据有以下特性:

数据存储在用户浏览器中
设置,读取方便,可以做到刷新页面也不丢失数据
容量约为5m,满足绝大部分需求

本地存储分为两类,分别是可以永久存储在本地的 localStorage和在当前浏览器临时使用的sessionStorage

localStorage

localstorage可以将数据永久存储正在本地(用户的电脑),除非手动删除,否则关闭网页也会存在。

特性:

可以多窗口共享(同一浏览器内)

语法:

方法 作用
setItem(key, value) 存储/修改数据
getItem(key) 读取数据
removeItem(key) 删除数据

数据的增删查改是以键值对的形式,key为键,可以理解为数据的名称;value为值,即对应数据的值。
比如存储一个张三的年龄:localStorage.setItem("张三", 18)

在浏览器中,我们也可以查看存储的数据:
JavaScript:BOM操作_第8张图片
通过localStorage存储的数据会永久存储在本地,就算关闭浏览器也依然会存在:
我们修改代码后,直接访问张三试试:
JavaScript:BOM操作_第9张图片
可以看到,这一次我们的代码中没有输入语句,但是我们可以直接访问张三的年龄了,这是因为上一次已经将数据存在用户的电脑中了,不论何时在浏览器打开,都可以直接访问这个值。


sessionStorage

sessionStorage会将数据临时存储下来,当用户关闭浏览器,数据就会被自动删除。

特性:

生命周期为关闭浏览器窗口
同一个窗口下的数据可以共享

其语法和localStorage是完全一致的,此处不再做详解了。
语法:

方法 作用
setItem(key, value) 存储/修改数据
getItem(key) 读取数据
removeItem(key) 删除数据

复杂数据类型的存储

先前讲过两种存储数据的方法,我们现在利用这个存储方式尝试存储一个对象:

JavaScript:BOM操作_第10张图片
最后我们没有输出对象的值,而是输出了[object object],也就是说对象这种复杂数据类型,不能直接存储。
为了可以存储复杂数据类型,JavaScript推出了JSON字符串,其是一种专门用来存储对象的字符串。

JSON字符串

将对象转化为JSON字符串的语法:

JSON.stringify(对象)

现在转化一个对象为JSON字符串,看看JSON字符串是一个什么样的形式:
JavaScript:BOM操作_第11张图片
可以看到,JSON字符串其实就是将所有的属性放在了同一行,并转化为了键值对的形式,其会为每一个属性名添加双引号,比如name变成了“name”,除此之外,和我们的基本语法别无二致。

被转化为字符串后,字符串就可以存储下来了。
JavaScript:BOM操作_第12张图片
那么我们要如何取用这个数据呢?
JSON的另外一个方法可以将JSON字符串转化为对象
语法:

JSON.parse(JSON字符串)

我们通过这个语法来取用数据:
在这里插入图片描述
可以看到,我们直接取用,得到的是一个字符串,而通过JSON.parse(JSON字符串)后,我们最后获得的就是一个对象了。


你可能感兴趣的:(前端开发,javascript,前端,开发语言)