BOM对象

一、什么是BOM

  • 浏览器对象模型(Browser Object Model)。主要用在客户端浏览器的管理。

  • 一直没有被标准化,不过各个主流浏览器都支持BOM,浏览器提供商会按照各自的想法随意去扩展它

  • 它使 javascript 有能力与浏览器进行“对话”。

二、window对象

  • BOM 的核心对象是 window,它表示浏览器的一个实例。是客户端浏览器对象模型的基类。
  • 在浏览器中,window 对象有双重角色,它既是通过 JavaScript 访问浏览器窗口的一个接口,又是 ECMAScript 规定的 Global 对象。
  • 这意味着在网页中定义的任何一个对象、变量和函数,都以 window 作为其 Global 对象,因此有权访问 isNaN()isFinite()parseInt()parseFloat() 等方法

2.1 全局作用域

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

// 定义全局作用域
window.a = 1;
window.f1 = function () {
    alert(2);
}
console.log(a);
f1();

// console.log(b,c,d);//全部报错 找不到变量
function f1(){
    var a = b = c = d = 2;
    console.log(a,b,c,d);//2 2 2 2
}
f1();
console.log(b,c,d);// 2 2 2

2.2 访问客户端对象

使用 window对象可以访问客户端其他对象,这种关系构成浏览器对象模型。

  • navigator:包含客户端有关浏览器的信息
  • screen:包含客户端屏幕的信息(使用较少)
  • history:包含浏览器窗口访问过的URL历史信息
  • location:包含当前网页文档的URL信息
  • document:包含整个HTML文档,可以用来访问文档内容及其所有页面元素

2.3 使用系统对话框

  • 浏览器通过 alert()confirm() 和 prompt() 方法可以调用系统对话框向用户显示消息。
  • 系统对话框与在浏览器中显示的网页没有关系,也不包含 HTML。它们的外观由操作系统及(或)浏览器设置决定,而不是由 CSS 决定。
  • 通过这几个方法打开的对话框都是同步和模态的。也就是说,显示这些对话框的时候代码会停止执行,而关掉这些对话框后代码又会恢复执行。

2.3.1 alert()

  • 它向用户显示一个系统对话框,其中包含指定的文本和一个 OK(“确定”)按钮。
  • 通常使用 alert() 生成的“警告”对话框向用户显示一些他们无法控制的消息,例如错误消息。
  • 用户只能在看完消息后关闭对话框。
alert("密码错误")

2.3.2 confirm()

  • 这种“确认”对话框很像是一个“警告”对话框。但二者的主要区别在于“确认”对话框除了显示OK按钮外,还会显示一个 Cancel(“取消”)按钮,两个按钮可以让用户决定是否执行给定的操作。
  • 为了确定用户是单击了OK还是Cancel,可以检查 confirm() 方法返回的布尔值:true 表示单击了OK,false 表示单击了Cancel或单击了右上角的 X 按钮。

if (confirm("吃了吗")) {
    alert("嗯嗯");
} else {
    alert("没有");
}

2.3.3 prompt()

  • 这是一个“提示”框,用于提示用户输入一些文本。
  • 提示框中除了显示 OK 和 Cancel 按钮之外,还会显示一个文本输入域,以供用户在其中输入内容。
  • prompt() 方法接受两个参数:要显示给用户的文本提示和文本输入域的默认值(可以是一个空字符串)。
  • 如果用户单击了 OK 按钮,则 promp() 返回文本输入域的值;如果用户单击了 Cancel 或没有单击 OK 而是通过其他方式关闭了对话框,则该方法返回 null

var result = prompt("你叫什么名字", "");
if (result !== null) {
    alert("Welcome, " + result);
}

2.4 打开和关闭窗口

  • 使用 window.open() 方法既可以导航到一个特定的 URL,也可以打开一个新的浏览器窗口。
  • 这个方法可以接收3个参数:要加载的URL、窗口目标、一个特性字符串控制窗口外观
    • url:需要载入的地址
    • 新窗口的名称:_self _blank
    • 新窗口的属性:窗口的大小 位置。例如:width=300,height=300,left=200,top=100
  • 窗口名.close()可以关闭窗口,如果关闭自身 那就使用 window.close()。close() 方法仅适用于通过 window.open() 打开的弹出窗口
var newWin = null;
oBtn1.onclick = function () {
    // 当书写新窗口打开 并且书写窗口大小位置的时候,会开一个新的浏览器窗口
    // window.open("http://www.baidu.com","_blank","width=300,height=300,left=200,top=100");

    // 当不写第三个参数的时候,_blank是打开一个新的标签页
    // window.open 返回一个值代表的是这个窗口,可以供我们对窗口操作
    newWin = window.open("http://www.baidu.com","_blank");
}

oBtn2.onclick = function () {
    // 关闭新窗口
    newWin.close();

    // 关闭自身(目前浏览器已经不支持关闭自身)
    // window.close();
}

2.5 超时调用和间歇调用

JavaScript 是单线程语言,但它允许通过设置超时值和间歇时间值来调度代码在特定的时刻执行。前者是在指定的时间过后执行代码,而后者则是每隔指定的时间就执行一次代码。

2.5.1 超时调用

  • 超时调用需要使用 window 对象的 setTimeout() 方法,能够在指定的时间段后执行特定代码
  • var TimerID = setTimeout(code,delay,....);
    • 参数code表示要延迟执行的字符串型代码,将在Window环境中执行,如果包含多个语句,应该使用分号进行分隔
    • delay表示延迟时间,以毫秒为单位
    • setTimeout方法的第一个参数虽然是字符串,但是也可以是一个函数,一般建议把函数作为参数传递给setTimeout方法,等待延迟调用
    • 如果setTimeout方法的第1个参数是一个函数,则 setTimeout方法第二个参数之后可以接收任意多个参数,这些参数将作为该函数的参数使用
  • 该方法返回值是一个 TimerID,这个ID编号指向延迟执行的代码控制句柄。如果把这个句柄传给 clearTimeout方法,则会取消代码的延迟执行
// code是一个字符串的书写格式
window.setTimeout("alert(1)",1000)
eval("alert(2)");

// 如果code是一个函数的书写格式1
window.setTimeout(function(){
    alert("延迟了2秒");
},2000)

// 如果code是一个函数的书写格式2
function f() {
    alert("延迟了3秒");
}
window.setTimeout(f,3000)

//传参的两种方法
function f(a,b){
    alert(a+b)
}
var a = window.setTimeout("f(1,2)",1000)
var b = window.setTimeout(f,1000,1,2);
console.log(a, b);//计数器返回值是一个id

2.5.2 取消超时调用

利用cleartimeout方法在特定的条件下清除延迟处理代码。方法的参数是setTimeout方法的句柄

  • 练习1

    // 页面打开延迟3秒弹出警告信息,当用户点击按钮以后,可以取消弹出
    var oBtn = document.getElementById("btn");
    var timer1 = setTimeout(function () {
        alert("oh");
    },3000)
    oBtn.onclick = function () {
        clearTimeout(timer1);
    }
  • 练习2

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>超时计时器</title>
        <style>
            *{
                margin: 0;
                padding: 0;
                list-style: none;
            }
            #box{
                width: 300px;
                border: 1px solid #000;
                position: relative;
            }
            #box h2{
                height: 40px;
                background-color: red;
            }
            #con{
                width: 300px;
                height: 200px;
                position: absolute;
                left: 0;
                top:40px;
                background-color: #2ba5eb;
                display: none;
            }
        </style>
    </head>
    <body>
        <div id="box">
            <h2>我是标题</h2>
            <div id="con">
                我是内容
            </div>
        </div>
        <script>
            var oBox = document.getElementById("box");
            var oCon = document.getElementById("con");
            var timer = null;
            oBox.onmouseenter = function () {
                clearInterval(timer);
                oCon.style.display = "block";
            }
            oBox.onmouseleave = function () {
                // oCon.style.display = "none";
                timer = setTimeout(function () {
                    oCon.style.display = "none";
                },300)
            }
        </script>
    </body>
    </html>

2.5.3 间歇调用

  • setInterval()方法能够周期性执行指定的代码,如果不加以处理,那么该方法将会被持续执行,直到浏览器窗口关闭或者跳转到其他页面为止。

  • var TimerID = setInterval(code,interval);

  • 该方法的用法与setTimeout()方法基本相同,其中参数code表示要周期执行的代码字符串,参数interval表示周期执行的时间间隔,以毫秒为单位

  • 该方法返回值是一个TimerID,这个ID编号指向对当前周期函数的执行引用,利用该值对计时器进行访问,如果把这个值传递给clearTimeout()方法,则会强制取消周期性执行的代码。

//每隔1s弹出您好
var timer = setInterval(function(){
    alert("您好");
},1000)

2.5.4 取消间歇调用

利用clearInterval方法在特定的条件下清除延迟处理代码。方法的参数是setInterval方法的句柄。

  • 练习1

    书写一个倒计时5秒到达战场

    <!-- // 书写一个倒计时5秒到达战场 -->
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>间隙调用计时器</title>
    </head>
    <body>
        <h2 id="con">敌军还有<span id="sec">5</span>秒到达战场</h2>
    <script>
        var oSec = document.getElementById("sec");
        var oCon = document.getElementById("con");
        var i = 5;
        var timer1 = setInterval(function () {
            i --;
            if (i <= 0){
                oCon.innerHTML = "全军出击";
                clearInterval(timer1);
            }
            oSec.innerHTML = i;
        },1000)
    </script>
    </body>
    </html>
  • 练习2

    动画:点击按钮,让元素向移动

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>间歇计时器案例</title>
        <style>
            #box{
                width: 100px;
                height: 100px;
                background-color: red;
                position: absolute;
                left: 0;
                top: 100px;
            }
        </style>
    </head>
    <body>
    <button id="btn">点我看box走一下</button>
    <div id="box">
    
    </div>
    <script>
        var oBox = document.getElementById("box");
        var oBtn = document.getElementById("btn");
        // 给一个变量保存当前元素的left值
        var oBoxLeft = 0;
        // 计时器一般在全局定义(因为你可能再其他的位置清计时器)
        var timer1 = null;//现在不使用 但是将来要使用 需要提前定义变量  可以给null
        oBtn.onclick = function () {
            /*一般我们保证一个运动只有一个计时器运行就可以了,但是我们每次重复点击,都会再额外的添加计时器进去
            所以我们在每次重复点击的时候,要把之前它身上的计时器给清掉,然后重新添加即可*/
            clearInterval(timer1);
    
            // 每隔多少毫秒 让box的定位值加一定的数值,可以达到动画效果
            // 一般控制元素的样式或者是位置,都是先对变量进行计算 然后再赋值过去
            timer1 = setInterval(function () {
                oBoxLeft ++;
                // 判断临界值使用变量判断即可
                if (oBoxLeft >= 1000){
                    clearInterval(timer1);
                }
                oBox.style.left = oBoxLeft + "px";
            },1)
        }
    
    </script>
    </body>
    </html>

2.5.5 计时器函数的this指向

  • 计时器函数是在window中运行的 计时器中的this基本上都是指向window的
setTimeout(function () {
    console.log(this);//window
},1000)

var obj = {
    fn1:function () {
        console.log(this);
    }
}
obj.fn1();//obj

// 在这里 obj.fn1仅仅是保存了一个函数 然后我们点击了以后调用的函数  所以指向document
document.onclick = obj.fn1;//document

// 在这里 obj.fn1仅仅是保存了一个函数  然后浏览器到达一定时间调用函数  所以指向window
setTimeout(obj.fn1,1000)//window

2.5.6 计时器面试题

  • 面试题1

    //计时器和事件一样 都是异步代码 。让同步代码(for)执行完成以后 才会去执行异步代码,当去执行异步代码的时候 for已经执行完毕 i此时是5了。
    for (var i = 0; i < 5; i++) {
        setTimeout(function () {
            console.log(i);
        },0)
    }
  • 面试题2

    对上边的代码进行修改,让弹出 0,1,2,3,4

    for (var i = 0; i < 5; i++) {
        (function fn(i) {
            //只要在这个函数中 出现i  那么就不会去使用for循环的i
            // 形参i 其实就是这个作用域的变量
            setTimeout(function () {
                console.log(i);
            },0)
        })(i);
    }

三、navigator对象

3.1 navigator概念

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

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

  • 常见属性:

    • onLine:表示浏览器是否连接到因特网
    • platform:浏览器所在的系统平台
    • userAgent:浏览器的用户代理字符串
      // online网络连接事件
      window.addEventListener("online",function() {
          alert("网络连接已建立");
      });
    
      // offline网络连接事件
      window.addEventListener("offline",function() {
          alert("网络连接已断开");
      });

3.2 浏览器检测方法

检测浏览器类型的方法有多种,常用的方法包括两种:特征检测法和字符串检测法,这两种方法都存在各自的优点与缺点,用户可以根据需要进行选择.

  • 特征检测法

    • 特征检测法就是根据浏览器是否支持特定功能来决定相应操作的方式。这是一种非精确判断法。但却是最安全的检测方法
    • 因为准确检测浏览器的类型和型号是一件很困难的事情,而且很容易存在误差,如果不关心浏览器的身份,仅仅在意浏览器的执行能力,那么使用特征检测法就完全可以满足需要
    • 当使用一个对象、方法或属性时,先判断它是否存在,如果存在,则说明浏览器支持该对象、方法属性,那么就可以放心使用
    if (document.documentElement){
        var w = document.documentElement.clientWidth
    } else{
        var w = document.body.clientWidth
    }
  • 字符串检测法

    • 客户端浏览器每次发送HTTP请求时,都会附带有一个user-agent(用户代理)字符串,对于Web开发人员来说,可以使用用户代理字符串检测浏览器类型

    • userAgent字符串包含了web浏览器的大量信息,如浏览器的名称和版本。

    var ua = navigator.userAgent.toLowerCase();
    var info = {
        ie:/msie/.test(ua) && !/opera/.test(ua),
        op:/opera/.test(ua),
        sa:/version.*safari/.test(ua),
        ch:/chrome/.test(ua),
        ff:/gecko/.test(ua) && !/webkit/.test(ua)
    }
    info.ie && console.log("ie");
    info.op && console.log("op");
    info.sa&& console.log("sa");
    info.ch && console.log("ch");
    info.ff && console.log("ff");

3.3 操作系统检测方法

  • navigator.userAgent返回值一般都会包含操作系统的基本信息,不过这些信息比较散乱,没有统一的规则。

  • 用户可以检测一些更为通用的信息,如检测是否为 Windows系统,或者为 Macintosh系统,而不去分辨操作系统的版本号

  • 例如,如果仅检测通用信息,那么所有 Windows版本的操作系统都会包含"Win”字符串,所有Macintosh版本的操作系统都包含有"Mac”字符串,所有Umix版本的操作系统都包含有"X11”,而 Linux操作系统会同时包含"X11”和" Linux

    var isWin = (navigator.userAgent.indexOf("Win") != - 1);
        // 如果是Windows系统,则返回true
    var isMac = (navigator.userAgent.indexOf("Mac") != - 1); 
        // 如果是Macintosh系统,则返回true 
    var isUnix = (navigator.userAgent.indexOf("X11") != - 1); 
        // 如果是UNIX系统,则返回true
    var isLinux = (navigator.userAgent.indexOf("Linux") != - 1); 
        // 如果是Linux系统, xc则返回true

四、location对象

  • location对象存储了与当前文档位置(URL)相关的信息,简单地说就是网页地址字符串,使用 window对象的loaction属性可以访问

  • location对象定义了8个属性,其中7个属性可以获取当前URL的各部分信息,另一个属性(href)包含了完整的URL信息

    • href : 声明或获取当前文档完整的URL

    • protocol:协议部分包括后缀的冒号。例如http:

    • host:主机和端口名称 www.baidu.com:8080

    • hostname:主机名称

    • port:端口号

    • pathname 路径部分

    • search:url的查询部分,包括前导问号

    • hash:锚部分包括前导 #

      // location对象属性(哈希值在地址栏中不会影响页面的跳转 浏览器在请求服务器时是不管他的)
      console.log(location.hash);
      
      // host:主机名:端口号
      console.log(location.host);//localhost:63342
      
      //hostname:主机名
      console.log(location.hostname);//localhost
      
      // prot:端口号
      console.log(location.port);//63342
      
      // pathname:路径名  在服务器中 当前页面的路径名称
      console.log(location.pathname);
      
      // href:url地址 完整路径
      console.log(location.href);
      
      // search 查询字符串  路径问号后跟的数据
      console.log(location.search);
  • location还定义两三方法:reload()和replace() assign()

    • assign:和href相当

    • reload:重新加载文档

    • replace:可以装载一个新文档而无须为它创建一个新的历史记录。替换当前文档的历史记录

      // location的方法
      var oBtn1 = document.getElementById("btn1");
      var oBtn2 = document.getElementById("btn2");
      var oBtn3 = document.getElementById("btn3");
      oBtn1.onclick = function () {
          location.assign("http://www.baidu.com");
      }
      oBtn2.onclick = function () {
          location.replace("http://www.baidu.com");
      }
      oBtn3.onclick = function () {
          // location.reload(true);//硬刷新
          location.reload(false);
      }
  • 练习

    倒计时跳转

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>倒计时跳转</title>
    </head>
    <body>
    <button id="btn">点击我注册成功</button>
    <h2><span id="time">3</span>秒后进行跳转</h2>
    <script>
        var oBtn = document.getElementById("btn");
        var oTime = document.getElementById("time");
        var timer = null;
        oBtn.onclick = function () {
            var reduceTime = 3;
            timer = setInterval(function () {
                reduceTime --;
                oTime.innerHTML = reduceTime;
                if(reduceTime <=0 ){
                    clearInterval(timer)
                    // location.href 也可以设置页面跳转
                    // location.href = "http://www.baidu.com";
                    // location.assign("http://www.baidu.com");
                    location.replace("http://www.baidu.com");
                    // window.open("http://www.baidu.com");
                }
    
            },1000)
        }
    </script>
    </body>
    </html>

五、history对象

  • history对象存储了客户端浏览器的浏览历史,通过window对象的history属性可以访问该对象
  • 在历史记录中后退:window.history.back(),相当于返回
  • 在历史记录中前进:window.history.forward(),相当于前进
  • 移动到指定的历史记录点,使用go方法从当前会话的历史记录中加载页面。上一页就是-1,上上一页就是-2
  • length属性可以了解历史记录栈中一共有多少页 window.history.length
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>01</title>
</head>
<body>
<h1>01</h1>
<a href="02.html">02</a>
<a href="03.html">03</a>
<button id="forward">前进</button>
<button id="back">后退</button>
<button id="go">走你</button>
<script>
    var oForward = document.getElementById("forward");
    var oBack= document.getElementById("back");
    var oGo = document.getElementById("go");
    oForward.onclick = function () {
        history.forward();
    }
    oBack.onclick = function () {
        history.back();
    }
    oGo.onclick = function () {
        history.go(-2)
    }
</script>
</body>
</html>
posted @ 2023-01-12 22:33  z_bky  阅读(45)  评论(0)    收藏  举报