js BOM

js基础:js基础入门语法
jsDOM:js DOM

五、BOM浏览器对象模型
1、BOM概述

BOM(Browser Object Model) 即浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window。由一系列相关对象构成,且每个对象都提供了很多方法和属性。

BOM缺乏标准,js语法的标准化组织是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape(网景公司)浏览器标准的一部分。所以有些兼容性较差。

(1)DOM vs BOM

DOM

  • 文档对象模型
  • DOM就是把文档当做一个对象来看待
  • DOM的顶级对象是document
  • DOM主要学习的是操作页面元素
  • DOM是W3C标准规范

BOM

  • 浏览器对象模型
  • 把浏览器当做一个对象来看待
  • BOM的顶级对象是window
  • BOM学习的是浏览器窗口交互的一些对象
  • BOM是浏览器厂商在各自浏览器上定义的,兼容性较差
(2)BOM构成

BOM比DOM更大,它包含了DOM。

​ window

-----------------------------------------------------------------

​ document location navigation screen history

window对象是浏览器的顶级对象,它具有双重角色。

  1. 他是js访问浏览器窗口的一个接口
  2. 他是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。调用的时候可以省略window,之前学习过的对话框也属于window对象方法,如alert()、prompt()等。
  3. window下有一个特殊属性window.name
2、window对象常见事件
(1)窗口加载事件

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

<script>
        window.onload = function () {
            var btn = document.querySelector('button');
            btn.addEventListener('click', function () {
                alert('点击我');
            })
        }
    </script>
    <button>点击</button>

注意:

  1. 有了window.onload就可以把js代码写到页面元素的上方(甚至是任何一个位置),因为onload会等页面内容全部加载完毕,再去执行处理函数的。
  2. window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。
  3. 但使用addEventListener则没有限制
		window.addEventListener('load', function () {
            var btn = document.querySelector('button');
            btn.addEventListener('click', function () {
                alert('点击我');
            })
        })
        window.addEventListener('load', function () {
            alert(22);
        })

document.addElementListener('DOMContentLoaded', function() {});

DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表、图片、flash等等。但ie9以上才支持

如果页面的图片很多的话,从用户访问到onload触发可能需要较长的时间,交互效果就不能实现,必然影响用户体验。此时用DOMContentLoaded事件比较合适。

document.addEventListener('DOMContentLoaded', function () {
            alert(33);
        })

几种加载事件的区别:

  • load等页面内容全部加载完毕,包含页面dom元素 图片 flash css等等
  • DOMContentLoaded 是DOM加载完毕,不包含图片 flash css等就可以执行 加载速度比load更快
(2)调整窗口大小事件
window.onresize() = function() {}
window.addEventListener('resize', function(){})
  1. 只要窗口大小发生像素变化,就会触发这个事件。
  2. 经常利用这个事件完成响应式布局。window.innerWidth 表示当前屏幕的宽度
		window.addEventListener('load', function () {
            var div = document.querySelector('div')
            window.addEventListener('resize', function () {
                console.log(window.innerWidth);
                console.log('浏览器尺寸变化了');
                if (window.innerWidth <= 800) {
                    div.style.display = 'none';
                } else {
                    div.style.display = 'block';
                }
            })
        })

实现了当浏览器宽度小于800px的时候,让div盒子隐藏;当浏览器宽度大于800px时,再让div盒子显示的效果。

3、定时器
  • setTimeout()
  • setInterval()
(1)window.setTimeout(回调函数, [延迟的毫秒数]);

用于设置一个定时器,该定时器在定时器到期后执行调用函数。

  1. 这里的window可以省略
  2. 延迟时间的单位是毫秒,也可以省略,如果省略则默认为0
  3. 页面中可能会有很多的定时器,所以要给定时器加标识符(起名字)
		setTimeout(function () {
            console.log('时间到了');
        }, 2000); 

        function callback() {
            console.log('爆炸了');
        }
        setTimeout(callback, 3000);
        //setTimeout('callback()', 3000);  //这种写法不推荐

        // 页面中可能会有很多的定时器,所以要给定时器加标识符(起名字)
        var timer1 = setTimeout(callback, 3000);
        var timer2 = setTimeout(callback, 5000);
(2)回调函数callback

普通函数是按照代码顺序直接调用的,而这个函数需要等待时间,等时间到了才去调用这个函数,因此称为回调函数。

5秒 自动关闭广告demo
// 5秒 自动关闭广告
        var ad = document.querySelector('img');
        function fun() {
            ad.style.display = 'none';
        }
        var timer = setTimeout(fun, 5000);
(3)window.clearTimeout(ID)

清除定时器clearTimeout

  • window可以省略
  • ID就是定时器的标识符(也就是名字)
// 清除定时器clearTimeout
        var btn = document.querySelector('button');
        btn.addEventListener('click', function () {
            clearTimeout(timer);
        })
(4)window.setInterval(回调函数, [间隔的毫秒数])

每隔一段时间,就调用一次回调函数。其余与setTimeout几乎相同。

京东倒计时demo
  • 因为倒计时是不断变化的,所以需要定时器来自动变换(setInterval)
  • 三个黑色的盒子分别放置时、分、秒,利用innerHTML写入内容
  • 第一次执行也是间隔毫秒数,因此刚刷新页面会有1s空白。因此最好采用封装函数的方式,这样可以先调用一次这个函数,防止刚开始刷新页面有空白问题
		var hour = document.querySelector('.hour');
        var min = document.querySelector('.minute');
        var sec = document.querySelector('.second');
        var inputTime = +new Date('2021-8-17 19:33:50');  //用户输入时间总的毫秒数

        // 开启定时器之前,先执行一次函数,以避免刷新页面时会有1s的空白
        countDown();
        setInterval(countDown, 1000);

        function countDown(time) {
            var nowTime = +new Date();  // 返回的是当前时间总的毫秒数
            // 判断倒计时是否结束
            if (inputTime > nowTime) {
                var times = (inputTime - nowTime) / 1000;  //剩余时间的总秒数
                var h = parseInt(times / 60 / 60 % 24);
                h = h < 10 ? '0' + h : h;  //始终显示两位数 01 03这种
                hour.innerHTML = h;
                var m = parseInt(times / 60 % 60);
                m = m < 10 ? '0' + m : m;
                min.innerHTML = m;
                var s = parseInt(times % 60);
                s = s < 10 ? '0' + s : s;
                sec.innerHTML = s;
            }
        }
(5)window.clearInterval()

清除定时器。

发送短信demo
  • 按钮点击之后,会禁用 disabled 改为 true即可
  • 同时按钮里面的内容会变化,通过innerHTML来进行修改
  • 秒数的变化是通过定时器实现的
  • 倒计时结束,需要停止定时器,并复原按钮初始状态,同时将倒计时时间复原
	手机号码:<input type="number">
    <button>发送验证码</button>
    <script>
        var btn = document.querySelector('button');
        var time = 3;
        btn.addEventListener('click', function () {
            this.disabled = true;
            var timer = setInterval(function () {
                if (time == 0) {
                    // 清除定时器并复原按钮
                    clearInterval(timer);
                    btn.disabled = false;
                    btn.innerHTML = '发送验证码';
                    time = 3;  // 这里要将time值复原为3
                } else {
                    btn.innerHTML = '等待' + time + 's后重新发送验证码';
                    time--;
                }

            }, 1000);
        })
    </script>
this指向问题

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,一般情况下,this的最终指向是那个调用它的对象。

  1. 全局作用域或者普通函数中this指向全局对象window(注意定时器中的this指向window)

    // 1.全局作用域或者普通函数中this指向全局对象window
            // 注意定时器里的this也指向window
            console.log(this);
    
            function fn() {
                console.log(this);
            }
            fn();  // 其实相当于window.fn()
    
            setTimeout(function () {
                console.log(this);  //相当于window.console.log(this)
            }, 1000);
    
  2. 方法调用中,谁调用this指向谁

    // 2.方法调用中谁调用this指向谁
            var o = {
                sayHi: function () {
                    console.log(this);  //指向调用该方法的对象o
                }
            }
            o.sayHi();
    
            var btn = document.querySelector('button');
            btn.onclick = function () {
                console.log(this);  //指向btn这个按钮对象
            }
    
            btn.addEventListener('click', function () {
                console.log(this);  //指向btn这个按钮对象
            })
    
  3. 构造函数中的this指向实例对象

    // 3.构造函数中this指向构造函数的实例
            function Fun() {
                console.log(this);
            }
            var fun = new Fun();
    
4、 JS 执行机制

javascript语言的一大特点就是单线程,也就是说,同一时间只能做一件事。这也就意味着,所有的任务需要排队,前一个结束,后一个才会执行。那么就会造成:如果js执行时间过长,就会导致页面渲染不连贯的问题,导致页面渲染加载阻塞。

(1)同步和异步

为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程。于是,js中出现了同步和异步的问题。

  • 同步:前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的。

    比如,我们要烧水煮饭,等饭好了,再去切菜,炒菜。

  • 异步:在做一件事的时候,因为这件事会花费很长时间,在做这件事的同时,还可以处理其他事情。

    比如,在煮饭的同时,我们去切菜,炒菜。

本质区别:流水线上各个流程的执行顺序不同。

(2)同步任务

同步任务都在主线程上执行,形成一个执行栈。

(3)异步任务

js的异步是通过回调函数实现的。

一般而言,异步任务有以下三种类型:

  • 普通事件,如 click、resize等
  • 资源加载,如 load、error等
  • 定时器,包括setInterval、setTimeout等

异步任务相关的回调函数添加到任务队列中(任务队列也称为消息队列)。

		console.log(111);
        setTimeout(() => {
            console.log(222);
        }, 0);
        console.log(333);

主线程执行栈 任务队列(消息队列)

console.log(111);

setTimeout(fn, 0); function () { console.log(222) }

console.log(333);

(4)执行机制
  1. 先执行执行栈里的同步任务
  2. 异步任务(回调函数)放入任务队列中
  3. 一旦执行栈中所有同步任务都执行完毕,系统则会按次序兑取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

由于主线程不断重复获取任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)

5、location对象

window对象给我们提供了一个location属性用于获取或设置窗体的URL,并可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。

(1)URL

统一资源定位符(Uniform Resource Locator, URL) 是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应如何处理它。

URL的一般语法格式:

protocol://host[:post]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成说明
protocol通信协议 常用的http,ftp,maito等
host主机(域名) www.itcast.cn
port端口号 可选 省略时使用方案的默认端口 如http使用80端口
path路由 由0或多个’/'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址
query参数 以键值对的形式 通过&符号分隔开
fragment片段 #后面内容常见于链接锚点
(2)location对象的属性
location对象的属性返回值
location.href获取或者设置 整个URL
location.host返回主机(域名)
location.port返回端口号 如果未写则返回空字符串
location.pathname返回路径
location.search返回参数
location.hash返回片段 #后面的内容
		var btn = document.querySelector('button');
        btn.addEventListener('click', function () {
            // console.log(window.location.href);
            location.href = 'http://www.baidu.com';
        })

        // 5秒后自动跳转页面
        var div = document.querySelector('div');
        var timer = 5;
        setInterval(function () {
            if (timer === 0) {
                location.href = 'http://www.baidu.com';
            } else {
                div.innerHTML = '您将在' + timer + '秒后跳转到新的页面';
                timer--;
            }
        }, 1000);
(3)获取URL参数
  • 第一个登录页面,里面有提交表单,action提交到index.html页面

  • 第二个页面,可以使用第一个页面的参数,这样实现了一个数据不同页面之间的传递效果

  • 第二个页面之所以能使用第一个页面的数据,是利用了URL里面的location.search参数

  • 在第二个页面中,需要把这个参数提取

    先去掉’?’ 利用substr

    再利用’=‘分割键和值 split(’=’)

<!--login.html-->

	<form action="index.html">
        用户名: <input type="text" name="username">
        <input type="submit" value="登录">
    </form>
<!--index.html-->

	<div></div>
    <script>
        console.log(location.search);
        // 1.先去掉'?' substr(start, length);  第二个参数可省略,默认取到字符串结尾
        var params = location.search.substr(1);  // username=andy;
        console.log(params);
        // 2.利用'='把字符串分割成数组 split('=')
        var arr = params.split('=');
        console.log(arr);

        var div = document.querySelector('div');
        div.innerHTML = arr[1] + ',欢迎你';
    </script>
(4)location对象的方法
location对象方法返回值
location.assign()跟href一样,可以跳转页面(也称为重定向页面) 记录浏览历史,可以后退
location.replace()替换当前页面,因为不记录历史,所以不能后退页面
location.reload()重新加载页面,相当于刷新按钮或者f5 如果参数为true 强制刷新ctrl+f5
		var btn = document.querySelector('button');
        btn.addEventListener('click', function () {
            // assign 是记录浏览历史的,所以可以实现后退功能
            // location.assign('http://www.baidu.com');

            // replace 不记录浏览历史,无法后退页面
            // location.replace('http://www.baidu.com');

            // reload 刷新页面f5
            location.reload();
            // reload 参数为true则强制刷新 ctrl+f5 不使用缓存
            location.reload(true);
        })
6、navigator对象

navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。

7、history对象

history对象与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)访问过的URL。

history对象方法作用
back()后退
forward()前进
go(参数)前进后退功能 参数如果是1 前进1个页面;如果是-1 后退1个页面
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值