【十二】JavaScript之BOM

发布时间 2023-07-04 14:30:21作者: Chimengmeng

【十二】JavaScript之BOM

【1】什么是BOM

  • BOM(Brower Object Model,浏览器对象模型),主要是浏览器中js解释器提供给开发者调用浏览器功能的对象或接口方法

  • 因为旧版本浏览器厂商实现不一样,所以有可能存在同一段代码在不同旧浏览器下的结果不一致的兼容问题。

  • 当然现代浏览器几乎不存在兼容问题了。

  • 实际上来说,BOM操作就是学习几个对象提供的属性和方法。

对象 描述
window 是浏览器中代表了当前网页创建的超全局对象,是js操作浏览器中的最高顶级对象,一个浏览器下可以有多个window对象。
location 地址栏对象
history 历史记录对象
navigator 浏览器版本信息对象
screen 屏幕对象[少用]
document 文档对象[只有少部分是属于BOM操作的,大部分是属于DOM操作]

【2】window

  • window是js提供的超全局对象,针对js提供给开发者使用的一切操作,都是属于window对象直接提供或间接提供的。
  • 包括我们前面学习的弹窗函数、定时器、内置函数与内置对象等等实际上都是window提供的子对象或函数。
  • 那么,同时,我们自己声明的变量或函数,实际上也有被window作为属性或方法来引用。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="1.css">
</head>
<body>
<script>
    // 在前面的学习中,所有的交互效果[弹窗函数,定时器,内置函数等等,实际上都是window提供的]
    console.log(window);

    // window 对象,顶级对象,是整个浏览器中提供给开发者操作DOM的最高级别的对象
    // 在全局作用域下,我们声明的变量事实上就是给window声明的属性
    // 在全局作用域下,我们声明的函数事实上就是给window声明的方法

    // 当然,我们如果要操作window对象的属性或方法,事实上是可以不写window的。
    // console.log(window)
    // console.log(this)  // 在全局作用域下打印this,也是当前对象
    // function close_page(){
    //     close()  // 是 window.close() 的简写
    // }
    //
    // var num = 20;
    // console.log(window.num) // 一般是省略掉window
    
    
    // // 在新版本浏览器提供的BOM操作,
    // // 实际上还提供了用于替代setInterval定时器的功能函数叫requestAnimationFrame与CancelAnimationFrame。
    // let timer = null
    // let time = parseInt((new Date() - 0) / 1000)
    // let start_time = time;
    // function func(){
    //     if(time == parseInt((new Date() - 0) / 1000)){
    //         console.log(time);
    //         time++;
    //     }
    //     cancelAnimationFrame(timer);
    //     if(start_time+10 >= parseInt((new Date() - 0) / 1000)){
    //         timer = requestAnimationFrame(func);
    //     }
    // }
    // func();


    // 通过元素对象本身的style只能获取行间样式
    console.log('背景颜色=',document.body.style.backgroundColor);
    // 想要获取当前元素通过内部样式或者外部样式的css属性值,是不能通过style属性来获取的,
    // 而是要通过getComputedStyle来获取浏览器中css样式表对象,来提取对应的内部或外部样式里面的值,
    // getComputedStyle 仅仅提供了获取样式值而已,不提供属性设置。
    console.log( getComputedStyle(document.body)["background-color"] );

    // 浏览器窗口显示内容区域的宽高度
    console.log(window.innerHeight);
    console.log(window.innerWidth);

    // 浏览器窗口的整体宽高度
    console.log(outerHeight);
    console.log(outerWidth);


</script>
</body>
</html>

【3】location

  • 地址栏管理对象
属性 描述
href 当前页面的url地址完整内容
protocol 当前页面的url地址的协议名称,常见的协议:httphttpsfileftpwswss
host 当前页面的url地址的完整的服务器主机地址或者完整站点域名。格式:主机名+端口
hostname 当前页面的url地址的服务器主机名或者站点域名
port 当前页面的url地址的服务器端口
origin 当前页面的url地址的主机地址,格式:协议+IP+端口或者协议+域名+端口
pathname 当前页面的url地址对应的服务端资源路径
search 当前页面的url地址的查询字符串,就是?号后面的内容
方法 描述
location.assign(url) 页面跳转,切换当前浏览器显示导航地址为指定url地址
localtion.reload() 页面刷新,相当于手动F5
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
   // console.log(location)
   /**
     * url地址的固定格式:
     *    协议名称://IP或域名:端口/路径?查询字符串#锚点
     *    protocol://hostname:port/pathname?query_srting#hash

    * protocol 协议,web中常见的协议:http、https、ws、wss、file、ftp
     * 域名(域名一般需要到域名商处购买,按年购买):
     *      顶级域名(一级域名): baidu.com
     *      二级域名: www.baidu.com   music.baidu.com  tieba.baidu.com
     *      三级域名: python.tieba.baidu.com
     *      ....
     * 端口: 一般如果是协议本身的默认端口,可以不填。http协议的默认端口是80,https端口时443
     * 路径:表示当前访问的资源(文件/数据)在目标服务器中的具体地址
     * 查询字符串(query_string/query_params),在js中也叫search,
     *      ?name=xiaoming&page=1&xxx=xxx&....
     * 锚点(hash):指定的是当前显示的内容在网页中的位置
     */
    // // 获取地址栏上的信息
    // console.log(location.href)   // 获取完整地址信息
    // console.log(location.origin) // 获取服务器的地址信息
    // console.log(location.pathname) // 获取当前页面所在的路径地址
    // console.log(location.search)   // 获取当前页面的查询字符串

    // 操作地址栏
    setInterval(()=>{
        console.log("hello")
        location.reload()  // 相当于F5,重载当前页面,就是刷新当前页面
    },5000);

    // 页面跳转
    function jump_baidu(){
        location.assign("http://www.baidu.com")
        // location.href = "http://www.baidu.com"  // 新版本的js中不再建议使用,建议使用assign方法
    }

    jump_baidu();

</script>
</body>
</html>

【4】history

  • 历史操作对象

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<button onclick="goto1()">前进一个页面</button>
<button onclick="back1()">后退一个页面</button>
<script>
    console.log(history);
    // 浏览器历史中关于当前窗口操作的历史信息数量
    console.log(history.length);

    // 操作历史记录
    function goto1(){
        // history.go(1); // 控制浏览器的页面前进一个页面,这是在浏览器有前进的历史记录的情况下
        // go 在有足够数量的历史记录的情况下,可以设置其他的数量的跳转,不仅可以正数前进跳转,还可以负数后退跳转
        history.forward()
    }
    
    function back1(){
        // history.go(-1); // 控制浏览器的页面后退一个页面,这是在浏览器有后退的历史记录的情况下
        history.back()
    }
</script>
</body>
</html>

【5】其他子对象或方法属性

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // 浏览器的代理信息
    console.log(navigator.userAgent);

       // 屏幕对象
    console.log(screen)
    // 获取当前浏览器所在屏幕的分辨率(width x height)
    console.log(screen.width)
    console.log(screen.height)
</script>
</body>
</html>

【6】本地存储

  • 本地存储是HTML5中由浏览器提供给我们开发者用于保存数据到浏览器中的2个对象。
    • 这2个对象的使用方式是一样的,但是存储时间的有效时间不一样。
  • 注意:
    • 本地存储的数据都是按域名/IP:端口来分开存储的。
    • 所以不同域名下的内容互不干扰的,甚至同一个域名不同端口保存数据都是相互隔离的。
    • 与cookie类似,但是cookie是属于旧时代的前端技术,已经在web开发中逐步被淘汰了,所以本地存储实际上就是替代cookies保存客户端数据的一种方式。
对象 描述
localStorage 永久存储, 只要不是主动删除,则数据都会一直在浏览器中
sessionStorage 会话存储, 基于浏览器窗口保存数据,当用户关闭了浏览器页面以后,则数据会被删除掉,或新建窗口无法原窗口数据。

示例

  • 因为2个对象的操作方式都一模一样的
    • 所以我们这里拿localStorage来举例
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    *{
        margin: 0;
        padding: 0;
    }
    div{
        width: 200px;
        height:200px;
        background-color: red;
    }
    </style>
</head>
<body>
<div></div>
<script>
    // 添加数据到本地存储中
    localStorage.setItem("属性名","数据")
    localStorage.属性名="数据"

    localStorage.setItem("name","root")
    localStorage.status = 100

    // // 修改本地存储中的数据
    // // 本地存储中的属性名是唯一的,所以针对同一个属性名的值进行修改即可
    // localStorage.name="xiaoming"

    // 获取本地存储中的数据
    // localStorage.("变get量名")
    // localStorage.变量名
    var ret = localStorage.getItem("status")
    console.log(ret) // 文本格式数据,所以一般复杂的数据保存到本地存储中,都是经过JSON或者base编码处理的


    // // 删除本地存储中一个或全部数据
    // localStorage.removeItem("name")
    // // 清空当前域名在本地存储中的所有数据,慎用
    // localStorage.clear()

</script>
</body>
</html>

小练习

  • 基于todolist功能
    • 实现前端数据保存带本地存储中。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
    body, ul, input{
        margin: 0;
        padding: 0;
    }
    ul{
        list-style: none;
    }
    .todolist{
        width: 600px;
        margin: 40px auto 0;
        background: #fff;
        box-shadow: 2px 2px 20px 0 rgba(0,0,0,.3);
    }
    .top{
        padding-top: 15px;
        margin: auto;
        width: 300px;
    }
    .top input[name="task"]{
        height: 22px;
        line-height: 22px;
        width: 204px;
        margin-right:1px;
        padding: 5px;
        font-size: 14px;
        border: 1px solid #aaa;
        outline: none;
        transition: all .5s linear;
    }
    .top input[name="task"]:hover{
        border: 1px solid #333;
    }
    .todolist button{
        height: 34px;
        line-height: 34px;
        font-size: 14px;
        border: none;
        outline: none;
        width: 80px;
        color: #333;
        background-color: #eee;
        cursor: pointer;
        transition: all .5s linear;
    }
    .todolist button:hover{
        background-color: #ccc;
    }
    .tasklist{
        width: 400px;
        margin: 20px auto;
        padding-bottom: 20px;
    }
    .tasklist li{
        font-size: 14px;
        height: 28px;
        line-height: 28px;
        margin-bottom: 4px;
        border-bottom: 1px solid #eee;
        color: #333;
        cursor: pointer;
        transition: all .5s linear;
    }
    .tasklist li:hover{
        border-bottom: 1px solid #aaa;
        background-color: #eee;
    }
    .tasklist li:after{
        display: block;
        content: "";
        clear: both;
    }
    .tasklist li .title{
        float: left;
    }
    .tasklist li button{
        float: right;
        height: 24px;
        line-height: 24px;
        width: 40px;
        margin: 0 5px;
        font-size: 12px;
    }
    </style>
</head>
<body>
    <div class="todolist">
        <div class="top">
            <input type="text" name="task" placeholder="请输入任务"><button class="btn">添加</button>
        </div>
        <ul class="tasklist">

        </ul>
    </div>
    <script>
    var task = document.querySelector('input[name="task"]');
    var btn = document.querySelector('.btn');
    var taskList = document.querySelector('.tasklist');

    var taskData = []
    // // 从永久存储中读取数据
    // if(localStorage.data){
    //     taskData = JSON.parse(localStorage.getItem("data"));
    // }

    // 从会话存储中读取数据
    if(sessionStorage.data){
        taskData = JSON.parse(sessionStorage.getItem("data"));
    }

    function showData(taskList, taskData){
        // 让数组中所有成员经过循环添加到ul列表中
        let content = ""
        for(let item of taskData.entries()){
            content += `
            <li>
                <span class="title">${item[1]}</span>
                <button onclick="deleteTask(${item[0]})">删除</button>
                <button onclick="moveUp(${item[0]})">↑</button>
                <button onclick="moveDown(${item[0]})">↓</button>
            </li>`
        }
        taskList.innerHTML = content;
        // // 保存数据到永久本地存储
        // localStorage.setItem("data", JSON.stringify(taskData))
        // 保存数据到会话本地存储
        sessionStorage.setItem("data", JSON.stringify(taskData))

    }

    showData(taskList, taskData);

    btn.onclick = function(){
        // 把用户添加的任务追到成员到taskData数组中
        taskData.push(task.value);
        // 显示数据
        showData(taskList, taskData);
        // 清空掉输入框的内容
        task.value = "";
    }

    function deleteTask(index){
        // 删除计划
        console.log("要删除的数据的下标:", index);
        // 根据下标删除数据中对应的计划任务
        taskData.splice(index,1);
        // 显示数据
        showData(taskList, taskData);
    }

    function moveUp(index){
        /**
         * 把计划向上移动
         */
        // 如果任务就在最上面,则不需要移动
        if(index === 0){
            return false; // 阻止代码继续往下执行
        }
        // 先把当前任务从任务列表中删除
        let task = taskData.splice(index,1)[0];
        console.log(task);
        // 在任务列表中的下标前一个位置插入
        taskData.splice(index-1, 0, task);
        // 显示数据
        showData(taskList, taskData);
    }


    function moveDown(index){
        /**
         * 把计划向下移动
         */
        // 如果任务就在最上面,则不需要移动
        if(index === taskData.length-1){
            return false; // 阻止代码继续往下执行
        }
        // 先把当前任务从任务列表中删除
        let task = taskData.splice(index,1)[0];
        // 在任务列表中的下标前一个位置插入
        taskData.splice(index+1, 0, task);
        // 显示数据
        showData(taskList, taskData);
    }
    </script>
</body>
</html>