BOM 知识点

423 阅读8分钟

一、BOM 浏览对象类型

1. BOM概念

BOM(Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供了独立于内容的、可

以与浏览器窗口进行互动的对象结构。BOM 由多个对象组成,其中代表浏览器窗口的 Window

对象是 BOM 的顶层对象,其他对象都是该对象的子对象。

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

进、在浏览器中输入URL等。

2. window对象

  • window 对象是 BOM 中的一个顶层对象,其他的对象都是 window 的子对象。document 对象就是 window 的一个子对象

    console.dir(window.document);

  • 当调用 window 下的属性和方法时,可以省略 window。 所以我们调用方法时都没有用window调用,例如window.alert(1),我们一般直接写成alert(1)。

  • 在全局作用域定义的全局变量,都是 window 的一个属性

    var age = 18;
    console.log(window.age);
    
  • 注意:window下两个特殊的属性 window.name、window.top。

    • window 中 的特殊属性 name,如果定义新的变量,只会在原来的 name 属性上进行赋值,并且只能是字符串格式的值

      var name = 123;
      console.log(window.name); //输出的是字符串
      
    • top 属性 在 window 中,属性值指向的就是顶层对象 window,这个属性是只读的,不能后期更改。

3. 对话框

alert() :警示框

prompt() :提示框

confirm() : 让用户进行确认或者取消选择的对话框。confirm 方法有返回值,根据按钮点击情况,如果点击确定 返回 true,如果点击取消 返回 false。

// 让用户进行确认或者取消选择的对话框
btn3.onclick = function () {
  var isSure = confirm("请问,您确定要删除这条数据吗?");
  console.log(isSure);
};

注意:对话框方法都有兼容问题,一般在工作中我们会用显示和隐藏代替。

4. 加载事件

onload事件

我们可以给 window 对象或者 等元素添加 onload 加载事件,表示只有绑定事件的元素加载完毕才能触发事件,才能执行事件函数。

其中 window 对象加载完毕:指的是所有HTML结构加载完,并且外部引入资源(js、css、img、视频)也加载完毕。

  • 应用

    利用 window.onload 事件,可以将 js 代码提前到 html 结构之前。

    注意:一个页面中只能有一个 window.onload 事件。

5. 延时器

setTimeout()

• 延时器是 window 对象的一个方法,类似于定时炸弹

• 语法:window.setTimeout(func,time);

• 第一个参数:延时执行的函数,可以是匿名函数定义,或者是一个函数名的引用,注意不要

加 () 。

• 第二个参数:延时的时间,以毫秒计数,1000 毫秒等于 1 秒。

• 功能:在指定的时间后,延迟执行一个函数。

6. 清除延时器

clearTimeout()

• window 对象的一个方法

• 语法:window.clearTimeout(timeout);

• 参数:指定的延时器变量名引用。

• 功能:清除指定的延时器。

• 注意:清除的延时器需要存储到一个变量中,便于后期清除调用。

var timeout = window.setTimeout(function () {
  console.log("boom");
},2000);
// 清除延时器
window.clearTimeout(timeout);

7. 定时器

setInterval()

• 定时器是 window 对象的一个方法,相当于定时闹钟,每隔固定的时间响一次

• 语法:window.setInterval(func,interval);

• 第一个参数:每次执行的函数,可以是匿名函数定义,或者是一个函数名的引用,注意不要

加 () 。

• 第二个参数:时间间隔,以毫秒计数,1000 毫秒等于 1 秒。

• 功能:每隔一个指定的时间,周期性的执行一个函数。

window.setInterval(function () {
  console.log(i++);
},500);

8. 清除定时器

clearInterval()

• window 对象的一个方法

• 语法:window.clearInterval(timer);

• 参数:指定的定时器变量名引用。

• 功能:清除指定的定时器。

• 注意:清除的定时器需要存储到一个变量中,便于后期清除调用。

var timer = setInterval(function () {
  console.log(i++);
},500);
// 清除定时器
window.clearInterval(timer);

9. 清除定时器的问题

(1) 问题 1

• 将定时器的开始和停止过程书写在不同的事件函数内部,容易出现用户错误点击情况

1、多次点击开始,会造成加速:因为相当于开了多个定时器累计在一起

2、多次点击开始,不能够再停止:只能清除最新的定时器

  • 解决方法

    设表先关,每次开启新定时器之前,都清除一次前面的定时器

    start.onclick = function () {
      // 先清除定时器
      clearInterval(timer);
      timer = setInterval(function () {
        // 信号量进行自加
        nowLeft += 5;
        // 将最新的 nowLeft 的值赋值给元素的 css 属性
        box.style.left = nowLeft + "px";
      },100);
    };
    // 清除定时器
    end.onclick = function () {
      clearInterval(timer);
    };
    

(2) 问题 2

• 需求:要求元素走到指定位置停止,例如让元素停止在 500px 的位置.

• 问题:如果步长nowLeft设置的不合理,停止的位置可能不是正好在 500 处。

  • 解决方法

    • 拉终停表

    • 在定时器内部每次都要判断是否走到了终点,要不要停止定时器

    • 如果走到或超过了终点,强行拉到重点,并停止定时器

    start.onclick = function () {
      // 先清除定时器
      clearInterval(timer);
      timer = setInterval(function () {
        // 信号量进行自加
        nowLeft += 40;
        // 判断这一次的运动是否走到了500 的位置
        // 拉终停表,走到规定的终点位置
        if (nowLeft >= 500) {
          // 将变量的值强制赋值为 500
          nowLeft = 500;
          // 清除定时器
          clearInterval(timer);
        }
        // 将最新的 nowLeft 的值赋值给元素的 css 属性
        box.style.left = nowLeft + "px";
      },50);
    };
    

(3) 问题 3

• 需求:在规定时间内让元素走到规定的结束位置,时间间隔可以更改

• 例如:让元素在 2 秒钟内,left 属性从 0 走到 500px.

  • 解决方法

    • 步标整除

    • 总距离 = 步长 * 次数;

    • 时间间隔自定义,总时长固定

    • 求出总次数 = 总时间 / 时间间隔

    • 定义计数器变量,每执行一次定时器函数增加计数 1,直到执行达到总次数,停止定时器

// HTMLElement.offsetLeft 是一个只读属性,返回当前元素左上角相对于  HTMLElement.offsetParent 节点的左边界偏移的像素值。
// 相当于是box的初始left值
var nowLeft = box.offsetLeft;

10. location对象

  • location 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象

    location 可以获取或者设置浏览器地址栏的 URL

  • location对象的成员

    • assign() 委派:作用 与 href 属性一样,可以设置页面跳转的地址,记录历史

    • reload() 重新加载:类似于false效果, ctrl+f5 强制刷新,从服务器获取页面,相当于 true 的效果

      ​ 参数:true 强制从服务器获取页面,false 如果浏览器有缓存网页的话,会直接从缓存中获取页面

    • replace() 替换:替换掉地址栏中当前的网址,但是不记录历史

    • hash/host/hostname/search/href……

var btn = document.getElementById("btn");
btn.onclick = function () {
  // 输出URL地址
  console.log(location.href);
  // 重新赋值,可以跳转到新页面,并且记录历史
  location.href = "http://www.lagou.com";
  location.assign("http://www.lagou.com");
  location.replace("http://www.lagou.com"); //不记录历史,不能后退
  location.reload(true);//强制从服务器获取页面
}

11. URL

• 统一资源定位符 (Uniform Resource Locator, URL)

• URL的组成:scheme://host:port/path?query#fragment

• 例如:www.lagou.com:80/a/b/index.h…

• scheme:通信协议,常用的http,ftp,maito等

• host:主机,服务器(计算机)域名系统 (DNS) 主机名或 IP 地址。

• port:端口号,整数,可选,省略时使用方案的默认端口,如http的默认端口为80。

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

• query:查询,可选,用于给动态网页传递参数,可有多个参数,用'&'符号隔开,每个参数的名和值用'='符号隔开。例如:name=zs

• fragment:信息片断,字符串,锚点.

12. history对象

• history 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象

• history 对象可以与浏览器历史记录进行交互,浏览器历史记录是对用户所访问的页面按时

间顺序进行的记录和保存。

• history.back(); 后退

• history.forward(); 前进

• go()

history.go(1); 前进

history.go(-1); 后退

二、案例

1. 返回顶部特效

(1) scrollTop

返回元素的垂直滚动条的位置。

**提示:**当滚动条位于最顶部时,位置是 0。

// 获取页面卷动的距离
// document.body.scrollTop 不兼容
document.documentElement.scrollTop 

(2) onscroll事件

页面滚动事件

window.onscroll = function(){
  //判断卷动走的距离,如果超过10px, 就让header变低,让返回顶部按钮出现
  if(document.documentElement.scrollTop > 10){
    header.className = "header fixed";
    backtop.style.display = "block";
  }else {
    header.className = "header";
    backtop.style.display = "none";
  }
};

三、补充内容

1. JavaScript 代码规范

网址:github.com/standard/st…

可以进行查阅,了解,在工作中最好使用代码规范进行编译,更清楚明了。

  • 细则
    • 使用两个空格 – 进行缩进
    • 字符串使用单引号 – 需要转义的地方除外
    • 不再有冗余的变量 – 这是导致 大量 bug 的源头!
    • 无分号没什么不好。不骗你!
    • 行首不要以 (, [, or ``` 开头
    • 关键字后加空格 if (condition) { ... }
    • 函数名后加空格 function name (arg) { ... }
    • 坚持使用全等 === 摒弃 == 一但在需要检查 null || undefined 时可以使用 obj == null

2. 创建元素的三种方式

(1) document.write()

几乎不使用该方法,了解即可。

document.write("新的内容<p>新的段落</p>")

(2) innerHTML

性能问题:innerHTML 方法由于会对字符串进行解析,需要避免在循环内多次使用。 可以借助字符串或数组的方式进行替换,再设置给 innerHTML

批量添加标签用ele.innerHTML时,循环遍历。

var box = document.getElementById("box")
// 添加 1000 个 p 标签到 div中
for (var i = 0 ; i < 1000 ; i++) {
  // innerHTML 进行字符串拼接时,每次都要分析读取字符串中的标签语法
  // 并且每次都在原始结构上进行重新绘制
  // 拼接太多次,会有性能问题,每次都需要解析很多很多字符串
  box.innerHTML += '<p style="width: 100px;height: 2px;border: 1px solid #00f;"></p>'
}

(3) document.createElement()

性能问题:document.createElement 每添加到页面一次,导致页面结构尺寸变化,会触发DOM 回流,也会消耗一些性能

var box = document.getElementById("box")
var ele = document.createElement("div")
ele.innerText = "新的 div 盒子"
box.appendChild(ele)//当box是数组的时候会报错,所以只能用getElementById