BOM基础

BOM

专门操作浏览器窗口和软件的一套对象和方法的统称

问题:没有标准,有严重的兼容性问题

包括:window / location / history / navigator / document / screen / event

window

1. window对象三大角色

代替ES标准的global充当全局作用域对象,所有声明的全局变量和全局函数,都默认保存在window对象中

保存了所有”原生“的对象和方法

原生:

  • 不需要下载任何第三方的东西,就可以直接使用的对象和方法
  • 包括:ES + DOM + BOM

代表当前正在打开的这个浏览器窗口

证据:

  • window可以获得当前窗口的大小:2组

    a. 完整窗口大小:

    window.outerWidth

    window.outerHeight

    b. 仅文档显示去内部大小

    window.innerWidth

    window.innerHeight

  • window可以打开和关闭一个窗口

    window.open()

    window.close()

2. 打卡新链接的四种情况:

原理:

  • 每个窗口在内存中都有一个唯一的窗口名(看不见)
  • 浏览器规定,相同名称的窗口只能打开一个。如果硬要打开第二个同名窗口,则新窗口会覆盖旧的同名窗口
  • 所有窗口都有一个window.name属性,用来记录当前窗口的窗口名,所以起变量名时,不要用name

给窗口起名的方式:

  • <a href="url" target="任意自定义窗口名"></a>
    
  • window.open('url', '任意自定义窗口名')
    

预定义窗口名:

  • _self:表示用当前窗口自己的名字,作为新打开窗口的名字。结果,新打开的同名窗口,会覆盖当前窗口自己
  • _blank:表示不指定任何窗口名,浏览器就会在底层自动为每个窗口随机分配窗口名。因为随机分配的窗口名肯定不重复,所以可重复打开多个

在当前窗口打开,可后退

a. HTML

<a href="url" target="_self"></a>

b. JS

window.open('url', '_self')

在当前窗口打开,禁止后退

JS

location.repalce('url')

新窗口打开,可同时打开多个

a. HTML

<a href="url" target="_blank"></a>

b. JS

window.open('url', '_blank')

新窗口打开,只能打开一个

a. HTML

<a href="url" target="任意自定义窗口名字"></a>

b. JS

window.open('url', '任意自定义窗口名字')

history

内存中专门保存当前窗口打开后成功访问过的所有url的历史记录数组,浏览器不允许对history数组做任何修改操作,只开放了一个功能(前进、后退、刷新)

// 1. 前进一步
history.go(1)
// 2. 后退一步
history.go(-1)
// 3. 刷新
history.go(0)

location

专门保存浏览器地址栏中正在打开的一个url的信息的对象

1. 属性

分段获得url中各个部分的信息

// 获得完整的url
location.href
// 获得url中协议部分
location.protocol 
// 获得url中主机名+端口号
location.host
// 获得主机名
location.hostname
// 获得端口号
location.port
// 获得从主机名后的,/往后的相对路径
location.pathname
// 获得从?往后的查询字符串
location.search
// 获得从#往后的锚点地址
location.hash

2. 方法

// 当前窗口打开,禁止后退
location.replace('新url')
// 当前窗口打开,可后退
location.href = '新url'
// 刷新页面
location.reload()

专门保存浏览器信息的对象,今后只要想获得浏览器的配置信息时,都用navigator

// 获取浏览器的名称、内核和版本号
navigator.userAgent
// 获取浏览器中安装的所有插件信息的列表,navigator.plugins['完整插件名'] !== undefined 说明安装了该插件
navigator.plugins

event

事件:浏览器自动触发的或者用户手动触发的页面中内容或状态的改变

事件处理函数:当事件发生时,自动调用执行的函数

事件绑定:每个元素上都有一批on开头的事件属性,事件绑定就是提前将事件处理函数保存到元素的事件属性上,当事件发生时浏览器先找到元素身上对应的事件属性,自动调用事件属性中保存的事件处理函数

1. 事件绑定的三种方式

a. 在HTML中手工绑定:**

<元素 on事件名="事件处理函数()">

b. 在js中以赋值方式绑定:**

查找触发事件的元素对象

绑定事件:元素对象.on事件名=function(){...this...}

问题:如果希望给一个元素的一个事件属性上同时绑定多个事件处理函数,就无法实现。后赋值的事件处理函数会把原事件处理函数覆盖掉。

c. 在js中以添加事件监听对象的方式绑定:

查找触发事件的元素

元素对象.addEventListener('事件名', 事件处理函数)

强调:

  • 添加事件监听时,事件名称不要加on前缀
  • 添加事件监听对象时,事件处理函数结尾不要加()

原理:

  1. 浏览器中有一个事件监听对象队列
  2. addEventListener做了两件事:
    • 新建一个事件监听对象,其中保存:当前元素对象,事件名和事件处理函数
    • 自动将事件监听对象添加到事件监听对象队列中
  3. 重复执行几次addEventListener就会反复添加几个重复的事件监听对象
  4. 将来发生的事情:
    • 浏览器先查找元素对象自己身上的事件属性中保存的事件处理函数,优先执行
    • 然后浏览器才会去事件监听对象队列中遍历查找所有符合要求(元素相同,事件名也相同)的事件监听对象。找到几个,就触发几个事件处理函数

d. 移除事件监听对象

元素.removeEventListener('事件名', 原事件处理函数)

注意:移除时查找的是事件名,元素对象以及函数地址相同的事件监听对象

坑:事件监听对象相同(包括事件处理函数的地址),则只能添加一个

解决:

  1. 用数组保存所有事件处理函数
  2. jQuery中解决

2. 事件模型

包括三个阶段:

捕获阶段:从数根节点开始,到当前触发事件的目标元素结束,由外向内依次遍历并记录各级父元素上是否绑定了事件处理函数。只记录,不执行

目标触发阶段:总是优先触发实际点击的目标元素(target)上的事件处理函数

目标元素(target):实际触发事件的那个元素对象

冒泡阶段:又从目标元素开始,到数根节点结束,由内向外一次触发各级父元素上绑定的事件处理函数

3. 事件对象

事件发生时,浏览器自动创建的,保存事件相关信息的对象

事件对象总是作为事件处理函数的第一个实参值(e / event),自动传入

使用事件对象的两种情况:

a. 想获得事件相关的信息

b. 想改变事件默认的行为

事件的功能:

a. 停止冒泡

e.stopPropagation()

事件冒泡/事件委托

浏览器触发事件采用的是遍历事件监听对象队列形式查找事件监听对象,故添加的事件监听对象越多,遍历事件越长,事件响应的速度越慢

可以通过事件委托(e.target)减少事件绑定的次数

问题:用户有可能会触发其他元素(不在期望内的元素)的事件

解决:事件处理函数中要先验证当前点击的目标元素的特征,是否符合要求。只要当目标元素符合要求才继续执行后续操作

强调:一切目标元素和其他元素不同的特征都可作为判断依据。比如 .className / .nodeName(标签名称) / .name / ...

阻止默认行为

问题:有些HTML元素身上有不想要的默认

比如:<a href="#">仅当作按钮用</a>会自动在地址栏url结尾添加#

解决:对于a有两种方式

  • <a href="javascript:;">文本</a>,意思是不让a跳转到其他页面,而是在当前页面的内容中执行一条JS空语句,只对a有效
  • e.preventDefault,这个对任意元素都有效

获取鼠标位置

a. 鼠标相对于屏幕左侧、上方的距离

e.screenX e.screenY

b. 鼠标相对于浏览器内部文档显示区左侧、上方的距离

e.clientX e.clientY

c. 鼠标相对于当前点击的HTML元素左侧、上方的距离

e.offsetX e.offsetY

posted @ 2021-10-26 22:36  carla-cn  阅读(93)  评论(0)    收藏  举报