《JavaScript 高级程序设计》第十二章 BOM 学习记录

367 阅读10分钟

1、window对象

  • BOM 核心是window对象,表示浏览器实例
  • 网页中定义的所有对象、变量和函数都有window作为其Global对象,都可以访问其上定义的全局方法。

1、Global作用域

  • 通过var生命的所有全局变量和函数都会成为window对象的属性和方法。
  • let、const 不会添加到全局
  • 访问未声明变量会抛错,可以用window对象查询是否存在可能未声明的变量。

2、窗口关系

  • top对象始终是最上层窗口,即浏览器窗口本身。
  • parent对象始终指向当前窗口的父窗口。
  • 如果当前窗口是最上层,parent等于top(都等于window)
  • 最上层的window如果不是通过window.open() 打开的,那么其name属性不会包含值。
  • self对象是终极window属性,始终指向window。是同一个对象,目的是为了和top,parent保持一致。
  • 这些属性都是window对象的属性。可以把多个窗口的window对象串联起来。

3、窗口位置与像素比

  • window对象的位置可以通过不同的属性和方法确定

    • scrollLeftscrollTop 表示在屏幕左侧和顶部位置

    • moveTo()moveBy() 移动窗口

      • 都接收两个参数
      • moveTo() 接收新位置的绝对坐标 x 和 y
      • moveBy() 接收相对当前位置在两个方向上移动的像素数
      // 窗口移动到左上角
      window.moveTo(0, 0)
      
      // 窗口向下移动100像素
      window.moveBy(0, 100)
      
      // 窗口移动到坐标位置
      window.moveTo(200, 300)
      
      // 窗口左移 50 像素
      window.moveBy(-50, 0)
      
      • 依浏览器,可能全部或部分禁用
  • 像素比

    • 背后是一个角度。目的是在不同设备上统一标准。

    • 低分辨率平板设备上12px 的文字应该和高清4K屏幕下12px的文字大小一样。

    • 不同像素密度的屏幕下就会有不同的缩放系数,以便把物理像素(屏幕实际分辨率)转为css像素(浏览器报告的虚拟分辨率)

      如手机屏幕物理分辨率可能是1920x1080,但因为像素可能非常小,浏览器就需要将其分辨率转为较低的逻辑分辨率,如640x320

    • 其中的转换比是window.devicePexelRatio属性提供的。对1920x1080转为640x320,其值就是3。12px实际上就会用36px的物理像素显示

    • window.devicePexelRatio实际上和每英寸像素数DPI是对应的。DPI表示像素密度,而window.devicePexelRatio表示物理像素和逻辑像素之间的缩放系数。

4、窗口大小

  • innerWidth、innerHeight
    • 返回浏览器窗口页面视口大小(不含浏览器边框和工具栏)
  • outerWidth、outerHeight
    • 返回浏览器窗口自身大小,无论是最外层window还是iframe
  • document.documentElement.clientWidth、documentdocumentElement.clientHeight
    • 返回页面视口的宽度和高度
let pageWidth = window.innerWidth
let pageHeight = window.innerHeight
if (typeof pageWidth != "number") {
  if (document.compatMode == "CSS1Compat") {
    pageWidth = document.documentElement.clientWidth;
    pageHeight = document.documentElement.clientHeight;
  } else {
    pageWidth = document.body.clientWidth;
    pageHeight = document.body.clientHeight;
  }
}
  • resizeTo()、 resizeBy() 调整窗口大小,接收两个参数

    • resizeTo()接收新的宽度和高度值

    • resizeBy()接收宽度和高度要缩放多少。

      // 缩放到100x100
      window.resizeTo(100, 100)
      
      // 缩放100, 50 即缩放到200x150
      window.reizeBy(100, 50)
      
    • 可能被浏览器禁用。缩放方法只能应用到最上层window对象。

5、视口位置

  • 度量文档相对于视口滚动距离的属性

    • window.pageXoffset /window.scrollX 和window.pageYoffset/window.scrollY

    • scroll() 、scrollTo()、scrollBy() 滚动页面。都接收表示相对视口距离的x和y坐标

      • scroll() 、scrollTo()表示要滚动到的坐标
      • scrollBy() 表示要滚动的距离
      // 相对于当前视图向下滚动100像素
      window.scrollBy(0, 100)
      
      // 相对于当前视图向右滚动40像素
      window.scrollBy(40, 0)
      
      // 滚动到页面左上角
      window.scrollTo(0, 0)
      
    • 接收ScrollToOptions字典,可以通过behavior表示是否平滑滚动

      // 正常滚动
      window.scrollTo({
        left: 100,
        top: 100,
        behavior: 'auto'
      })
      
      // 平滑滚动
      window.scrollTo({
        left: 100,
        top: 100,
        behavior: 'smooth'
      })
      

6、导航与打开新窗口

  • window.open() 可以用于导航到指定URL,也可以打新浏览器窗口。

    • 接收四个参数

      • 要加载的URL
      • 目标窗口
      • 特征字符串
      • 表示新窗口在浏览器的历史记录是否替代当前加载页面的布尔值
    • 如果第二个参数是已存在的窗口的名字,会在对应窗口打开URL

      // 等同<a href="http://www.wrox.com" target="toFrame">
      window.open("http://www.wrox.com", "topFrame")
      

1、弹出窗口

  • window.open 第二个参数不是已有窗口,会打开新窗口或标签页。
  • window.open 第三个参数即特定字符串,用于指定新窗口配置,如果不传则按照默认配置,如果打开的不是新窗口忽略这个参数
    • 配置包含fullscreen(仅IE) 、height、left、location、Menubar、resizeable、scrollbars、status、top、width。逗号分开等号连接
  • window.open返回一个对新建窗口的引用。
  • window.close() 仅适用于window.open()创建的窗口,不吭不经用户确认就关闭主窗口,但可以关闭弹出窗口,关闭后窗口引用只能用来检查closed属性。win.closed
  • 新建的窗口有一个opener属性,指向打开它的窗口,但不会记录自己打开的新窗口。
  • 某些浏览器,每个标签会运行在独立进程中,而window对象需要喝另一个标签页通信,那么标签便不能运行在独立的进程中。可以将标签页的opener属性设置为null,表示可以运行在独立进程中。

2、安全限制

  • 弹出窗口被在线广告滥用,所以增加安全限制。
    • 强制显示地址栏状态栏等
    • 用户操作才能创建窗口

3、弹窗屏蔽程序

  • 检测是否被屏蔽了

7、定时器

  • setTimeout 接收回调函数和延迟毫秒数(只是添加到任务队列)
    • 返回ID,用来clearTimeout() 清除。
  • setInterval 类似, 通过clearInterval() 取消,
    • 一个任务结束和下一个任务开始的时间间隔无法保证。 因为是定时插入任务

8、系统对话框

  • alert() 、confirm()、 prompt()
  • 会阻塞代码执行
  • window.print() window.find() 打印和查找对话框

2、location对象

  • 提供了当前窗口中加载文档的信息,以及导航功能。

  • 是window的属性也是document的属性

    http://foouser:barpassword@www.wrox.com:80/WileyCDA/?q= javascript#contents location的内容如下

    属性说明
    hash#contentsURL散列表
    hostwww.wrox.com:80服务器名及端口号
    hastnamewww.wrox.com服务器名
    href整个链接完整的URL
    pathname/WileyCDA/URL中路径和文件名
    port80端口号
    protocalhttp协议
    search?q=javascriptURL查询字符串
    username
    password
    originwww.wrox.comURL的源地址

1、查询字符串

let getQueryStringArgs = function () {
  // 取得没有开头问号的查询字符串
  let qs = (location.search.length > 0 ? location.search.substring(1) : ""),
    // 保存数据的对象
    args = {};
  // 把每个参数添加到 args 对象
  for (let item of qs.split("&").map(kv => kv.split("="))) {
    let name = decodeURIComponent(item[0]),
      value = decodeURIComponent(item[1]);
    if (name.length) {
      args[name] = value;
    }
  }
  return ages
}
  • URLSearchParams

    • 可以用来检查和修改查询字符串

    • 传入查询字符串

    • 暴露了get()、set()、delete()、has()等方法

    • 一般其实例也作为可迭代对象

    let qs = "?q=javascript&num=10"
    let searchParams = new URLSearchParams(qs)
    searchParams.toString() // q=javascript&num=10
    searchParams.has('num') // true
    searchParams.get('num') // 10
    

2、操作地址

  • assign() 方法传入URL location.assign("http://xxxx")
    • 会立即启动导航到新URL操作,增加一条历史记录
    • 如果给location.href和window.location 设置一个URL,也会以同一个URL值调用assign() 方法
    • 最常见的是设置location.href,修改其他属性(hash、search、hostname、pathname、port)也会修改当前URL。
    • 除了hash,只要修改location的一个属性就会重新加载新URL
    • 修改hash的值会在浏览器历史中增加一条新纪录
  • 如果不需要增加历史记录,可以使用replace()方法
  • location.reload()重新加载当前显示的页面
    • 参数表示是否强制从服务器重新加载
    • 位于reload() 之后的代码可能执行也也能不执行,取决于网络延迟和系统资源等因素。

3、navigator对象

  • 客户端标识浏览器的标准
属性/方法说明
appCodeName即使非Mozilla也返回“Mozilla”
appName浏览器全名 Netscape
appVersion浏览器版本 通常与实际不一致
connectionNetworkInformation对象
cookieEnabled是否启用了cookie
credentialsCredentialsContainer 对象
deviceMemory内存容量 GB单位
doNotTrack返回用户的"不跟踪"设置
geolocationGeolocation 对象
getUserMedia()返回与可用媒体设备硬件关联的流
hardwareConcurrency返回设备处理器核心数量
javaEnabled()浏览器是否启用了Java
language浏览器主语言
languages浏览器偏好的语言数组
locksLockManager对象
mediaCapabilitiesMediaCapabilities对象
mediaDevices可用媒体设备
maxTouchPoints设备触摸屏最大触点数
mimeTypes浏览器注册的MIME类型数组
onLine浏览器是否联网
permissionsPermissions 对象
platform浏览器运行的系统平台
plugins浏览器安装的插件数组
product产品名称 Gecko
productSub产品额外信息(版本)
registerProtocolHandler()将网站注册为特定协议的处理程序
requestMediaKeySystemAccess()返回一个期约,解决为MediaKeySystemAccess对象
sendBeacon()异步传输小数据
serviceWorker返回与ServiceWorker实例交互的ServiceWorkerContainer
storage()StorageManager对象
userAgent返回浏览器用户代理字符串
vendor浏览器厂商名称
vendorSub浏览器厂商更多信息
vibrate()触发设备振动
webdriver是否被自动化程序控制

1、检测插件

  • plugins数组

    • name 插件名称
    • description 插件介绍
    • filename 插件的文件名
    • length 有当前插件处理的MIME类型数量
    let hasPlugin = function(name) {
      name = name.toLowerCase()
      for(let plugin of window.navigator.plugins){
        if(plugin.name.toLowerCase().indexOf(name)>-1){
          return true
        }
      }
      return false
    }
    
  • IE10 使用new ActiveXObject() 的try/catch来检测

  • refresh() 方法刷新plugins属性反映新安装的插件,参数true表示所有包含插件的页面都会重新加载,否则只有plugins更新

2、注册处理程序

  • registerProtocolHandler()将网站注册为处理某种特定类型信息的应用程序
  • 传入参数:
    • 要处理的协议(如mailto / ftp)
    • 处理该协议的URL
    • 应用名称

4、screen对象

  • 客户端能力信息

    属性说明
    availHeight屏幕像素高减系统组件高
    availLeft没有被系统组件占用的屏幕最左侧像素
    availTop没有被系统组件占用的屏幕最顶端像素
    colorDepth屏幕颜色位数
    height屏幕像素高度
    left当前屏幕左边的像素距离
    pixelDepth屏幕的位深
    top当前屏幕顶端的像素距离
    width屏幕像素宽度
    orientation返回Screen Orientation API中屏幕朝向

5、history对象

1、导航

  • go() 在历史记录中沿任何方向导航
    • 参数表示前进或后退多少步
  • back() 后退, forward() 前进
  • length属性表示历史记录的条目
  • 通过hash来模拟前进后退不会触发页面刷新。

2、历史状态管理

  • hashchange 事件在页面URL的散列变化时触发,可以执行操作

  • 状态管理API可以让开发者改变浏览器URL而不加载新页面

  • 使用history.pushState()方法,参数

    • 一个state对象 (500KB-1MB)
    • 一个新状态的标题(未使用)
    • 一个(可选)相对URL
    let stateObject = {foo: 'bar'}
    history.pushState(stateObject, "title", "baz.html")
    
  • pushState方法执行后

    • 状态信息就会被推到历史记录
    • 浏览器地址栏显示新的相对URL
    • 即使location.href返回的是地址栏的内容,浏览器也不会向服务器发送请求
  • pushSate() 会创建新的历史记录,相应地启用“后退”按钮

  • 此时单击后退按钮会触发window上的popstate事件,有一个state属性,包含通过pushState() 第一个参数传入的state对象

  • 可以通过history.state获取当前的状态对象

  • replaceState() 传入 pushState()相同参数更新状态,不会创建新历史记录,只覆盖当前状态

  • 确保通过pushState创建的每个“假”URL背后都对应服务器上一个真实物理URL,否则刷新就会导致404.