JavaScript - BOM

269 阅读8分钟

这是我参与8月更文挑战的第17天,活动详情查看:8月更文挑战

BOM的概念

BOM(Browser Object Model) 是指浏览器对象模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM 由多个对象组成,其中代表浏览器窗口的 Window对象是 BOM 的顶层对象,其他对象都是该对象的子对象(document也是BOM的子对象, window可以省略不写, 所以我们平常只写document)。

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

window 对象

window 是浏览器的顶级对象,当调用 window 下的属性和方法时,可以省略 window。

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

注意:

window下两个特殊的属性 window.name、window.top。

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

  • top 属性 在 window 中,属性值指向的就是顶层对象 window,这个属性是只读的,不能后期更改。

所以定义全局变量的时候, 不要定义name和top.

对话框

一般不会直接使用对话框的语句, 因为会导致后面的代码不能执行, 所以一般使用一些<input>标签等进行模拟. 但在小案例中可以使用.

  • alert()
  • prompt()
  • confirm()
    // 让用户进行确认或者取消选择的对话框
    // confirm 方法有返回值,根据按钮点击情况,如果点击确定 返回 true,如果点击取消 返回 false
    btn3.onclick = function () {
      var isSure = confirm("请问,您确定要删除这条数据吗?");
      console.log(isSure);
    };

加载事件

onload 事件

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

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

注意:

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

可以在<head>中写JavaScript:

<script>
    // window.onload 事件,一个页面只能使用一次
    window.onload = function () {
      // 事件被触发时,页面所有内容都已经加载完毕,获取元素不会出现错误
      var box = document.getElementById("box");
      var pics = document.getElementsByTagName("img");
      console.log(box.clientHeight);
    };
  </script>
  1. 一个页面中只能有一个 window.onload 事件。

延时器

设置延时器

延时器是 window 对象的一个方法,类似于定时炸弹. 是一种异步语句.

语法:window.setTimeout(func,time); window可以省略

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

加 () 。

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

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

注意 延时器为了保证后期能够被清除,需要定义赋值给一个变量

    var timeout = window.setTimeout(function () {
      console.log("boom");
    },2000);

清除延时器

window 对象的一个方法

语法:window.clearTimeout(timeout);

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

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

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

    // 清除延时器
    window.clearTimeout(timeout);

定时器

设置定时器

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

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

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

  • 第二个参数:时间间隔,以毫秒计数,1000 毫秒等于 1 秒。 第一次执行函数时是在第一个时间间隔之后

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

注意 要想后期清除定时器,在定义的时候必须存到一个变量中

清除定时器

window 对象的一个方法

语法:window.clearInterval(timer);

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

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

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

清除定时器的问题

问题 1

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

1、多次点击开始,会造成加速

2、多次点击开始,不能够再停止

点击开始按钮,让 box 向右运动 ; 点击结束, 让box停止运动

<body>
    <input type="button" value="开始" id="start">
    <input type="button" value="结束" id="end">
    <div class="box" id="box"></div>
    <script>
        // 获取元素
        var start = document.getElementById("start");
        var end = document.getElementById("end");
        var box = document.getElementById("box");

        //信号量. 每次给它重新赋值, 实现变化
        //信号量初始值必须与属性初始值保持一致, left:0 所以nowLeft=0
        var nowLeft = 0;

        //定时器
        var timer;

        start.onclick = function () {
            //定时器, 制作运动过程
            timer = setInterval(function () {
                nowLeft += 10;
                box.style.left = nowLeft + "px";
            }, 100);
        };

        end.onclick = function(){
            clearInterval(timer);
        }
    </script>
</body>

在上面的代码中, 定时器的开始和结束写在了不同的函数中, 就会出现上面所说的两个问题. 定时器如果不消除就会一直存在, 每次点击开始按钮的时候, timer都由原来的定时器指向了一个新的定时器, 定时器的步长就会一直累加, 就算点击结束按钮也只能消除当前的定时器, 清除不了原来就存在的那些定时器.

解决方法 设表先关

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

即在start.onclick = function ()中加入一行清除定时器的语句:

        // 点击开始按钮,让 box 向右运动
        start.onclick = function () {
            clearInterval(timer);
            //定时器, 制作运动过程
            timer = setInterval(function () {
                nowLeft += 10;
                box.style.left = nowLeft + "px";
            }, 100);
        };

问题 2

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

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

解决方法 拉终停表

在定时器内部每次 (每次信号量增加)都要判断是否走到了终点,要不要停止定时器; 如果走到或超过了终点,强行拉到重点,并停止定时器.

        // 点击开始按钮,让 box 向右运动
        start.onclick = function () {

            clearInterval(timer);
            //定时器, 制作运动过程
            timer = setInterval(function () {
                nowLeft += 35;
                if(nowLeft >= 500){
                    //将变量强制拉到500
                    nowLeft = 500;
                    
                    clearInterval(timer);
                }
                box.style.left = nowLeft + "px";
            }, 100);
        };

问题 3

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

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

解决方法 步标整除

  • 总距离 = 步长 * 次数;

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

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

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

<body>
    <input type="button" value="开始" id="start">
    <input type="button" value="结束" id="end">
    <div class="box" id="box"></div>

    <script>
        // 获取元素
        var start = document.getElementById("start");
        var end = document.getElementById("end");
        var box = document.getElementById("box");

        var nowLeft = 0;
        var endLeft = 500;

        var time = 2000;
        var interval = 50;
        //次数累加器
        var count = 0

        //总次数
        var maxcount = time / interval;

        // 步长 = (结束位置 - 起始位置) / (总时长 / 时间间隔)
        step = (endLeft - nowLeft) / maxcount;

    
        var timer;

        start.onclick = function(){
            timer = setInterval(function() {
                nowLeft += step;
                count ++;

                if(count >= maxcount){
                    //拉终停表
                    nowLeft = endLeft;

                    clearInterval(timer);
                }


                box.style.left = nowLeft +"px";
            }, interval);
        }

    </script>
</body>

简单运动

原理

简单运动 是一种视觉暂留效果,只要元素变化过程时间够短,给人眼造成的效果就是一个 运动的效果,人眼的视觉残留的时间 0.1-0.4 秒之间。

制作方法 通过定时器,实现每隔一个极短的时间(50-100 毫秒左右),执行函数,函数 内部让运动的属性值发生变化。

提高运动速度的方法

1、缩短时间间隔,增加了每秒移动的次数。(改变setInterval中的时间间隔参数)

2、加大步长,让每一次走的步长增加。(改变信号量自加的值)

location 对象

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

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

location 对象的成员

使用 chrome 的控制台查看

查 MDN:developer.mozilla.org/zh-CN/

成员:

  • 方法: assign()/reload()/replace()

  • 属性: hash/host/hostname/search/href……

  1. assign 委派 assign() 方法的作用 与 href 属性一样,可以设置页面跳转的地址

  2. replace 替换
    功能:替换掉地址栏中当前的网址,但是不记录历史

  3. reload 重新加载

类似 键盘中 f5 功能,类似于false效果, ctrl+f5 强制刷新,从服务器获取页面,相当于 true 的效果.

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

  1. href 属性 重新赋值,可以跳转到新页面,并且记录历史

URL

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

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

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

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

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

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

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

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

history 对象

history 对象是 window 对象下的一个属性,使用的时候可以省略 window 对象. 但几乎不需要设置.

history 对象可以与浏览器历史记录进行交互,浏览器历史记录是对用户所访问的页面按时间顺序进行的记录和保存。

back() 回退历史记录访问

forward() 前进,查看之前记录的跳转后的页面

go() 指定跳转的页面

  • history.go(1) 前进一个页面
  • history.go(-1) 后退一个页面