第十篇 浏览器对象模型 - BOM

发布时间 2023-03-30 11:09:54作者: caix-1987

BOM (Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供独立于内容的、可以与浏览器窗口互动的对象结构

BOM 由多个对象组成,其中代表浏览器窗口的 window 对象是 BOM 的顶层对象,其他对象都是该对象的子对象

document 也是 BOM 的子对象,window 可以省略不写,所以我们平常只写 document

我们在浏览器中的一些操作都可以使用 BOM 的方式进行编程处理,比如:刷新浏览器、后退、前进、在浏览器中输入 URL 等

BOM 就是一套操作浏览器的API(接口/方法/属性)

BOM 中常见的对象

 window:  代表整个浏览器窗口 
 
    注意: window 是 BOM 中的一个对象, 并且是一个顶级的对象(全局),下面的对象都能通过它找到
    
 Navigator:  代表当前浏览器的信息, 通过 Navigator 我们就能判断用户当前是什么浏览器 
 
 Location:   代表浏览器地址栏的信息, 通过 Location 我们就能设置或者获取当前地址信息
 
 History:  代表浏览器的历史信息, 通过 History 来实现刷新/上一步/下一步 
 
      注意点: 出于隐私考虑, 我们并不能拿到用户所有的历史记录, 只能拿本次使用时的历史记录
      
 Screen:  代表用户的屏幕信息     
Window 对象

BOM 的核心对象是 window,它表示浏览器的一个实例

在浏览器中,window 对象有双重角色,它既是通过JS访问浏览器窗口的一个接口,又是 ES 规定的 Global 对象

这意味着在网页中定义的任何一个对象、变量和函数,都以 window 作为其 Global 对象,因此有权访问 parseInt()等方法

window 对象代表了浏览器窗口,页面可视区域,它还被复用为 Es 的全局对象 Global,所有的原生类型的构造函数和函数都从一开始就存在于这个对象之上

浏览器对象模型 BOM(Browser,Object,Model)是以 window 对象为基础的

window 全局作用域
由于 window对象同时扮演着 ES 中的 Global 对象的角色,因此所有在全局作用域中声明的变量,函数都会变成 window 对象的属性和方法

var age = 29;

console.log(window.age) => 29

let age_1 = 30

console.log(window.age_1) => undefined
window 窗口框架
   如果页面中包含框架,则每个框架都拥有自己的 window 对象,并且保存在 frames 集合中。在 frames 集合中,可以通过数值索引或者框架名称来访问相应的 window 对象,每个 window 对象都有一个name 属性,其中包含框架的名称
   
   在使用框架的情况下,浏览器中会存在多个 Global 对象。在每个框架中定义的全局变量会自动成为框架中 window 对象的属性,由于每个 window 对象都包含原生类型的构造函数,因此每个框架都有一套自己的构造函数,这些构造函数一一对应,但并不相等
   
   <iframe src="a.html" name="topFrame" frameborder="0"></iframe>
   
   <iframe src="b.html" name="bottomFrame" frameborder="0"></iframe>
   
   上面例子可以通过 window.frames[0] 或者 window.frames['topFrame'] 引用框架,最好使用 top 而非 window 引用,如 top.frames[0]
   
   console.log(top.frames[0])
   
   => window{...}
   
   console.log(window.frames["topFrame"])
   
   => window{...}
   
   另一个 window 对象是 parent ,parent 对象始终指向当前框架的直接上层框架
window 窗口位置属性
 window.screenLeft 窗口相对于屏幕左侧的距离 number (单位 px)
 
 window.screenTop 窗口相对于屏幕顶部的距离 number (单位 px)
 
 window.moveTo(x,y) 移动到 (x,y)坐标对应的新位置
 
 window.moveBy(x,y) 相对当前位置在两个方向上分别移动 x/y 个像素的距离
window 窗口大小属性
 使用窗口大小属性需要注意浏览器的兼容性问题
窗口外部尺寸

c1d71a1aa35f2abb456da31bc5937483.png

    窗口的外部大小由整个浏览器窗口的宽度和高度组成,包含地址栏,选项卡栏和其他浏览器面板
    
    window.outerWidth  浏览器窗口的宽度
    
    window.outerHeight 浏览器窗口的高度
窗口内部尺寸

2edbecd555701e97fa7738b113588f83.png

    窗口的内部大小(也称为视口大小)由显示网页的视口的宽度和高度组成,包含滚动条
    
    window.innerWidth 视口的宽度
    
    window.innerHeight 视口的高度
屏幕
屏幕尺寸

1daf133710445f0666507bd8b32f9f4a.png

    屏幕尺寸是屏幕的宽度和高度: 显示器或移动屏幕
    
    window.screen 是保存屏幕尺寸信息的对象
    
    window.screen.width 屏幕的宽度
    
    window.screen.height 屏幕的高度
可用屏幕尺寸

b28008790c4d873c72aac187431fa3cb.png

    可用的屏幕大小由活动屏幕的宽度和高度组成
    
    没有操作系统工具栏
    
    screen.availWidth: 可利用的宽,等于屏幕的宽
    
    screen.availHeight: 可利用的高,等于屏幕的高减去 mac 顶部栏或 windows 底部栏
屏幕距离

43527b27eed8d32d17469aee4c487efd.png

  screenTop: 浏览器窗口左上角到屏幕上边缘的距离
  
  screenLeft: 浏览器窗口左上角到屏幕左边缘的距离
  
    Firefox 浏览器不支持上述属性,但是可以使用
    
      screenX: 等于 screenLeft
      
      screenY: 等于 screenTop
客户区
   元素的客户区大小(client dimension),指的是元素内容及其内边距所占据的空间大小

a603c709830c0b0af7e602b67f93216b.png

   clientWidth: 内容可视区的宽度
   
   clientHeight: 内容可视区的高度
网页大小
 网页大小由呈现的页面内容的宽度和高度组成

994f60621638aec18c95e04aef98e75c.png

     scrollWidth: 
     
       实际内容的宽度
     
       没有滚动条时与 clientWidth 相同
       
       否则是等于 实际内容的宽度 + padding
       
       scrollWidth 也包括 ::before 和 ::after 这样的伪元素
       
     scrollHeight:
     
        实际内容的高度
        
        没有垂直滚动条时与clientHeight相同
        
        否则是等于 实际内容的高度 + padding
        
        scrollHeight 也包括 ::before 和 ::after这样的伪元素
滚动距离

129d86657877fd3b76db32ab277986df.png

    scrollLeft: 元素最左端和窗口中可见内容的最左端之间的距离。即当前左滚的距离
    
    scrollTop: 元素最顶端和窗口中可见内容的最顶端之间的距离。即当前上滚的距离
    
    如果有滚动条 scrollLeft = 隐藏内容宽度 + border
    
    如果没有滚动条 scrollLeft = 0
窗口事件
1、窗口加载事件:  window.onload

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

   有了 window.onload 就可以把 JS 代码写到页面元素的上方,因为 onload 是等页面内容全部加载完毕,再去执行处理函数

   window.onload 传统注册事件方式只能写一次,如果有多个,会以最后一个 window.onload 为准

   如果使用 addEventListener 则没有限制

  window.onload = function(){
    // js 代码
  }
  
  或者
  
  window.addEventListener('load',function(){
    // js 代码
  })
 
2、窗口加载事件  DOMContentLoaded

    DOMContentLoaded 事件触发时,仅当 DOM 加载完成,不包括样式表,图片,flash 等等
    
    如果页面的图片很多的话,从用户访问到 onload 触发可能需要较长的时间,交互效果就不能实现,必然影响用户的体验,此时用 DOMContentLoaded 事件比较合适
    
    DOMContentLoaded 是 DOM 加载完毕,不包含图片 flash css 等就可以,执行加载速度比 load 更快一些
    
    e9 以上才支持;
      document.addEventListener("DOMContentLoaded",function(){
     // js 代码
    })
  
3、调整窗口大小事件 resize

    window.onresize 是调整窗口大小加载事件,当触发时就调用的处理函数
    
    只要窗口大小发生像素变化,就会触发这个事件
    
    我们经常利用这个事件完成响应式布局
    
    使用 window.innerWidth 获取当前屏幕的宽度
    
    window.onresize = function () {};
    
    window.addEventListener("resize", function () {});
系统对话框
1、alert()

   确定提示框
   
   由浏览器向用户弹出提示性信息。该方法包含一个可选的提示信息参数。如果没有指定参数,则弹出一个空的对话框
   
2、confirm()

   选择提示框
   
   由浏览器向用户弹出提示性信息,弹出的对话框中包含两个按钮,分别表示“确定”和“取消”按钮。
   
   如果点击“确定”按钮,则该方法将返回 true;
   
   单击“取消”按钮,则返回 false。
   
   confirm() 方法也包含一个可选的提示信息参数,如果没有指定参数,则弹出一个空的对话框
   
3、prompt()

    输入提示框
    
    可以接收用户输入的信息,并返回输入的信息
    
    prompt() 方法也包含一个可选的提示信息参数,如果没有指定参数,则弹出一个没有提示信息的输入文本对话框。
定时器

window 对象包含 4 个定时器专用方法

 setTimeout(回调函数,延时时间(毫秒)); 倒计时结束之后调用函数
 
 clearTimeout(定时器名字): 清除 setTimeOut 的定时器;
 
 setInterval(回调函数,间隔时间): 每间隔多少时间就执行一次回调函数
 
 clearInterval(定时器名字): 清除 setInterval 的定时器;

区别

  setTimeout() 方法主要用来延迟代码执行,而 setInterval() 方法主要实现周期性执行代码。
  
  它们都可以设计周期性动作,其中 setTimeout() 方法适合不定时执行某个动作,而 setInterval() 方法适合定时执行某个动作
  
  setTimeout() 方法不会每隔固定时间就执行一次动作,它受 JavaScript 任务队列的影响,只有前面没有任务时,才会按时延迟执行动作。
  
  setInterval() 方法不受任务队列的限制,它只是简单的每隔一定的时间就重复执行一次动作,如果前面任务还没有执行完毕,setInterval()  可能会插队按时执行动作
其他窗口方法
  window.open() => 打开新窗口
  
  window.close() => 关闭当前窗口
  
  window.moveTo() => 移动当前窗口
  
  window.resizeTo() => 重新调整当前窗口
  
  ......
location 对象

window 对象给我们提供了一个 location 属性用于获取或设置窗体的 URL,并且可以用于解析 URL

因为这个属性返回的是一个对象,所以我们将这个属性也称为 location 对象

URL: 统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址

互联网上的每个文件都有一个唯一的 URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它

URL由三部分组成:资源类型、存放资源的主机域名、资源文件名

location 对象的属性

URL一般语法规格

protocol :// hostname[:port] / path / [;parameters][?query]#fragment

协议://主机名:端口号/路径/参数

路径:由零或多个“/”符号隔开的字符串,一般用来表示主机上的一个目录或文件地址

属性名 例子 说明
hash #index url中 # 后面的字符,没有则返回空字符串
host www.baidu.com:80 服务器名称和端口号
hostname www.baidu.com 域名 不带端口号
href www.baidu.con:8080/web/... 完整的 url
pathname web/javascript/text.js 服务器下面的文件路径
port 8080 url的端口号 没有则为空
protocol http 使用的协议
search ?id=10&name=caixin url的查询字符串,通常为 ? 后面的内容
自定义查询字符串参数返回对象
var url = window.location

function getQueryObj(){

  let location = window.location
  
  let queryStr = location.search.length > 0 ? location.search.substring(1) : ''
  
  let obj = {} , item;
  
  let queryArr = queryStr.length > 0 ? queryStr.split('&') : []
  
  for(let i = 0; i < queryArr.length; i++){
     
     item = queryArr[i].split('=');
     
     obj[item[0]] = item[1]
     
  }
  
  return obj

}

console.log(getQueryObj()) => {name:'caix',id:'10'}
修改 location

每次修改 location 的 hash 以外的任何属性,页面都会以新URL重新加载

 window.location = "http://www.baidu.com"
 
 location.search = "?name=caixin&age=35"
 
 location.hostname = "www.xiaomi.com"
 
 location.pathname = "web/html/a.html"
 
 location.port = "8088"
location.replace(url)
   除了 hash 值以外的任何修改,都会在浏览器的历史记录中生成一条新的记录
 
 可以通过浏览器的回退按钮导航到前一个页面
 
 可以通过 replace() 方法禁止这种行为
 
 使用 replace 打开的页面,不能返回到前一个页面
 
    loaction.replace('http://www.baidu.com')
 
 在浏览器控制台输入如上代码,浏览器将不支持回退
location.reload() 重新加载
  通过 location.reload() 方法可以重新加载页面 
  
  location.reload() 重新加载 (有可能会从缓存中加载)
  
  location.reload(true)  重新加载 (从服务器重中新加载) 
history 对象

history 对象保存着用户上网的历史记录

从窗口被打开的那一刻算起,因为 history 是 window 对象的属性

因此每个浏览器窗口,每个标签乃至每个框架,都有自己的 history对象与特定的 window 对象关联

history 对象 一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到

history 常用的有如下 3 个 方法 和 1 个属性:

1、history.go()

   接受一个 整数数字 或者 字符串 参数 
   
   向最近的一个记录中包含指定字符串的页面跳转
   
   history.go("caixin.com")  => 向前或者向后寻找指定字符串页面,没有找到则无响应
   
   history(3) => 向前跳转三个记录
   
   history(-1) => 向后跳转一个记录
   
2、history.forward()

   向前跳转一个页面
   
3、history.back()

   向后跳转一个页面
   
4、history.length

   获取历史记录数,如果是打开的第一个页面  则 history.length == 0
   
   可以用该属性来判断当前打开的网页是不是该窗口打开的首个网页

navigator 对象存储了与浏览器相关的基本信息,如名称、版本和系统等

通过 window.navigator 可以引用该对象,并利用它的属性来读取客户端基本信息

navigator 对象包含有关浏览器的信息,它有很多属性,我们最常用的是 userAgent

该属性可以返回由客户机发送服务器的 user-agent 头部的值

navigator.userAgent

下面前端代码可以判断用户哪个终端打开页面,实现跳转
      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 = ""; //电脑
  }
screen 对象
screen 对象 基本上只用来表明客户端的能力,其中包括了浏览器窗口外部的显示器信息,比如像素和宽高等,常用属性如下所示:

availHeight    => 屏幕的像素高度减去系统部件的高度

availWidth     => 屏幕的像素宽度减去系统部件的宽度

availLeft       => 未被系统部件占用的最左侧像素值

availTop       => 未被系统部件占用的最上侧像素值

height          => 屏幕像素高度

width           => 屏幕像素宽度
其他

26c776028e682e3f458716c91332e105.png

元素可视区 client

688d34d0d2377ae085639262d8d3dabc.png

Element.clientTop 和 Element.clientLeft 获取可视区域的偏移值(实际上就等于元素上下 border 值) 四舍五入(整数)后的结果

Element.clientWidth 和 Element.clientHeight 获取可视区域(padding + 元素内容区域的宽高,不包含滚动条)的宽高
元素偏移量 offset (块级元素,只读属性)
Element.offsetParent
   Element.offsetParent 是一个只读属性, 返回当前元素最近的一个父级定位元素
Element.offsetLeft && Element.offsetTop

f95e32023fbdbc81d0b5ec5bd2fbe0c5.png

Element.offsetLeft 和 Element.offsetTop 是一个只读属性

返回当前元素相对于父级元素左侧和上侧的偏移量
Element.offsetWidth && Element.offsetHeight

3dad78b0b1b8a62dbe13f63dc7a517d8.png

 Element.offsetWidth 和 Element.offsetHeight 是一个只读属性
 
 返回一个元素布局的宽高(元素布局包括: border、滚动条、padidng、内容块)
 
 该属性返回的值为一个四舍五入的整数
offset 和 style 的区别
offset

  offset 可以得到任意样式表中的样式值
  
  offset 系列获得的数值是没有单位的
  
  offsetWidth 包含 padding+border+width
  
  offsetWidth 等属性是只读属性,只能获取不能赋值
  
所以 我们想要获取元素大小位置 用 offset 更合适  

style

  style 只能得到行内样式表中的样式值
  
  style.width 获得的是带有单位的字符串
  
  style.width 获得不包含 padding 和 border 的值
  
  style.width 是可读写属性,可以获取也可以赋值
scroll ( 用于对可滚动元素进行求值 )
Element.scrollTop 和 Element.scrollLeft

fc51f62acbe71859427130b64454ab16.png

用于获取或设置元素被卷起的宽高(子元素顶部或左侧到当前元素可视区域顶部或左侧的距离)

对于不可滚动的元素 Element.scrollTop 和 Element.scrollLeft 值为 0

如果给 scrollTop(scrollLeft) 设置的值小于0,那么 scrollTop(scrollLeft) 的值将变为0。

如果给 scrollTop(scrollLeft) 设置的值大于元素内容最大宽度,那么 scrollTop(scrollLeft) 的值将被设为元素最大宽度(高度)。
Element.scrollWidth && Element.scrollHeight

ae2505a164767ad261db75c7b7d94a42.png

Element.scrollWidth 和 Element.scrollHeight 是只读属性, 表示元素可滚动区域的宽高; 实际上又等于 clientHeight/clientWidth + 未显示在屏幕中内容的宽高;

它们的值等于元素在不使用水平滚动条的情况下适合视口中的所有内容所需的最小宽度。

测量方式与 clientWidth(clientHeight) 相同:它包含元素的内边距,但不包括边框,外边距或垂直滚动条(如果存在)。 它还可以包括伪元素的宽度,例如::before或::after
 
如果元素的内容可以适合而不需要水平滚动条,则其 scrollWidth 等于 clientWidth; (最小值为元素的可视区域宽高: clientWidth (clientHeight))