JavaScript BOM 操作

249 阅读9分钟

JavaScript BOM 操作

前端 JavaScript DOM 和 BOM 学习目录

1. 认识DOM 和 BOM

2. DOM 操作节点、DOM 操作元素节点

3. DOM 获取任意元素 、节点类型、节点名称属性

4. DOM attribute property style属性 className属性 classList属性 Data

5. DOM 创建元素 移除元素 克隆元素

6. DOM 元素操作 window窗口操作

7. DOM Event事件

8. DOM 常用API事件总结

9. BOM 操作

10. JSON数据操作

BOM 初识

BOM 就是我们的浏览器对象模型(Browser Object Model

BOM 就是我们的浏览器提供的用来处理文档(document)之外的所有内容的其他对象

其中含有的就是我们的: navigator location history 等等对象的操作



首先我们需要知道的是我们的 Javascript 脚本代码的运行环境含有两种

这个概念也是我在前面经常说的两种环境,一种就是我们的 浏览器宿主环境,一种就是我们的 nodejs 环境

BOM 实现的就是我们的将浏览器和 JavaScript 脚本实现连接起来的桥梁



BOM 中常见的对象模型

window : 在这个对象模型里面含有了全局属性,全局方法,控制浏览器的相关属性以及方法

location: 浏览器连接到对象的位置(URL)

history: 操作浏览器的访问历史,即是说就是后面我们会学习框架开发中的路由

navigator: 用户代理(浏览器)的状态和标识

screen: 屏幕相关的信息

XMLHttpRequest 就是我们的网络请求



一说到运行环境,后面我们实实现微信小程序的开发的时候,我们就只是将我们的运行环境支持变为了我们的微信而已

同时还有一些去其他新的东西我们注意一下就可以了,转变是很方便的



BOM window 对象

首先在我们的 window 对象中,我们含有的对象含有我们的一些全局对象以及全局属性

ECMAScript 规范,就是需要提供一个全局对象

对于我们的浏览器环境的话,我们的全局对象就是我们的 window

对于我们的 nodejs 环境,我们的全局对象就是我们的 global

但是为了我们的全局对象的统一,这个时候就出现了新的可以用来指定两者的一个对象: globalThis



同时在我们的浏览器的宿主环境中,我们这个 window 全局对象也是 浏览器窗口对象

这个对象给我们提供了一些用来实现操作的浏览器的一些 API



window 对象中包含的属性以及方法含有:

包含了大量的属性: localStorage console location history screen...(60左右)

包含了大量的方法: alert close scrollTo open...(40左右)

包含了大量的事件: focus blur load hashchange...(30左右)

包含了从 EventTarget 继承的一些方法 addEventListener removeEventListener dispatchEvent

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        :root {
            --a-default-color: deepskyblue;
            --a-hover-color: darkred;
            --a-visited-color: #e36666;
        }
​
        body {
            padding: 0;
            margin: 0;
            .aEle {
                font-size: 18px;
                color: var(--a-default-color);
                text-decoration: var(--a-default-color) underline;
            }
​
            .aEle:hover {
                color: var(--a-hover-color);
                text-decoration: var(--a-hover-color) underline;
                cursor: pointer;
            }
​
            .aEle:visited {
                color: var(--a-visited-color);
                text-decoration: var(--a-visited-color) underline;
                cursor: pointer;
            }
        }
    </style>
</head>
<body>
<myEle class="aEle">打开百度</myEle>
<button>关闭窗口</button>
<script>
    // 开始实现使用我们的 open 方法来实现模拟 a 链接
    // open 方法含有两个参数一个就是我们的需要打开的链接(href) url, 一个就是打开的模式target
    document.querySelector(".aEle").addEventListener('click', function (e) {
        openUrl = open("https://www.baidu.com/", "_blank")
    })
    
    document.querySelector("button").addEventListener('click', function (){
        close(openUrl)
    })
</script>
</body>
</html>

注意的是,我们在后期实现书写属于自己的组件库的时候也是这样类似的思想,深刻理解元素语义化的意思



BOM location 对象

我们使用这个对象就是为了实现操作访问网页的 url

location 对象表示的是 window 上面当前实现链接到的 URL 信息



location 对象中的常见属性

我们在开发中可能需要获取的信息含有:

href —— 表示的当前window 对象对应的超链接 URL,整个URL

protool —— 当前的协议类型

host —— 主机地址

hostname —— 主机地址(莫得端口号)

port —— 端口

pathname —— 路径名称

search —— 查询字符串

hash —— 哈希值

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    window.addEventListener('click', function () {
        console.log(`当前的访问链接为: ${location.href}`)
        console.log(`当前访问链接地址为: ${location.protocol}`)
        console.log(`当前的访问主机为: ${location.host}`)
        console.log(`当前的访问主机名: ${location.hostname}`)
        console.log(`当前的访问端口为: ${location.port}`)
        console.log(`当前的访问路径为: ${location.pathname}`)
        console.log(`当前的查询字符为: ${location.search}`)
        console.log(`当前的路由hash值为: ${location.hash}`)
    })
</script>
</body>
</html>


location对象中的常见方法

assign : 实现是将我们旧访问的 URL 实现赋值为新的 URL,并且实现跳转到新的 URL 中

replace:实现的就是打开新的 URL,并且跳转到新的URL中(不会有访问记录存在)

reload: 实现的就是重新加载页面

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<button class="btn01">打开新的网页,并且留下访问记录</button>
<button class="btn02">打开新的网页,不留下访问记录</button>
<button class="btn03">重新加载网页</button>
<script>
    var btn01 = document.querySelector('.btn01')
    var btn02 = document.querySelector('.btn02')
    var btn03 = document.querySelector('.btn03')
​
    btn01.onclick = function () {
        location.assign("https://www.baidu.com/")
    }
​
    btn02.onclick = function () {
        location.replace("https://www.baidu.com/")
    }
​
    btn03.onclick = function () {
        location.reload()
    }
</script>
</body>
</html>


URLSearchParams

可以实现的是将将我们的字符串转化为 URLSearchParams 类型

同时也是可以将我们的 URLSearchParams 类型转化为 字符串类型

常使用的方法含有

get 获取我们的搜索参数对应的值

set 实现设置我们的搜索参数和值

append 实现添加我们的搜索参数和值

has 判断我们的搜索参数是否含有那些值

delete 实现的就是我们的删除某一个字段和其对应的值

同时我们需要注意的是,中英文的编码格式各有不同

中文会使用 encodeURLComponent 和 decodeURLComponent 来实现编码和解码

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    var searchParams = new URLSearchParams("name=juwenzhang&age=19")
    console.log(searchParams.get("name"))  // juwenzhang
    console.log(searchParams.toString())  // name=juwenzhang&age=19
​
​
    // 开始实现重新设置值
    // 使用该方法的时候,我们是具有两个参数的: 一个就是我们的参数列表字段,一个就是我们的参数值
    searchParams.set("other_name","76433")
    console.log(searchParams.get("other_name"))  // 76433
    console.log(searchParams.toString())
​
​
    // 开始实现添加操作
    searchParams.append("my_love_name", "水逆信封")
    console.log(searchParams.get("my_love_name"))   // 水逆信封
    console.log(searchParams.toString())  // name=juwenzhang&age=19&other_name=76433&my_love_name=%E6%B0%B4%E9%80%86%E4%BF%A1%E5%B0%81
​
    // 开始实现判断是否含有 name 参数
    console.log(searchParams.has("name"))  // true
​
    // 开始实习删除字段名
    searchParams.delete("my_love_name", "水逆信封")
    console.log(searchParams.toString())  // name=juwenzhang&age=19&other_name=76433
</script>
</body>
</html>

想用就直接看文档就行了😄😄 😄

image-20241104032522473.png



BOM history 对象

前言

前端的路由的核心就是,实现修改我们的 url ,但是我们的页面不实现刷新,这个就是我们的前端路由最核心的一点

默认情况下的话,我们的 url 改变了,我们的页面都是会发生向服务器发送新的请求,服务器返回资源,页面全部刷新

但是使用了前端路由就可以解决这个问题

最终的话前端路由还是和原生的 history 对象 息息相关的



前端渲染的意思就是实现的是我们通过修改我们的 url ,来实现渲染页面中我们自己想要渲染到页面的部分

在这个过程中,整个页面的搭建,我们是没有整个网页向后端实现整个网页该发送的发送请求的

我们请求的只是该部分需要重新加载的数据资源向后端发送了请求,这个就是前端路由,前端渲染



以前的工作模式就是,通过我们的 url 的改变,直接向我们的后端发送全部的请求

最后再来实现加载我们的页面,这个就是以前的 后端渲染页面



到了我们后面学习前端路由的时候,就可以发现一点,有两种前端路由模式,一种就是 history模式 和 hash模式

但是为什么是这两种模式呐?

因为当我们修改我们的 url 的 history 以及 hash 值的时候,整个页面是不会向我们的服务器发送整个页面的请求的

同时不会实现刷新整个页面



看过 vue 和 react 源码都可以发现一点:

history 和 hash 就是目前的话 vue 和 react 开发框架实现前端路由的底层原理

属性和方法

length 会话中的记录条数

state 当前保持的状态,就是我们的保持会话的数据有那些

back() —— 就是实现的是返回上一页

forword() —— 就是实现的是前进一页

go() —— 就是实现的是指定需要加载的页面

pushState() —— 打开新的一个指定地址

replaceState —— 打开新的地址,并且使用 replace

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<button class="btn">修改 url</button>
<button class="back">返回上一级路由</button>
<button class="forward">前进一级路由</button>
<script>
    // 1.history 的属性值
    console.log(history.length)
    console.log(history.state)
​
    // 2.修改 history
    var btnEl = document.querySelector('.btn')
    btnEl.addEventListener('click', function () {
        /**
         * 这个方法含有三个参数
         * state  就是传入一个 JS 中的数据,表示的是状态,可以拓展看 localStorage | sessionStorage
         * title 可有可无,""
         * url 新的地址参数
         * 这个就实现了修改我们的 url 地址,并且实现了页面不刷新
         */
        history.pushState({name: "juwenzhang", other_name: "76433", my_love_name: "水逆信封"},
            "", "juwenzhang")
​
        console.log(history.length)
        console.log(history.state)
    })
​
    // 实现返回上一级路由
    var backEl = document.querySelector('.back')
    backEl.addEventListener('click', function () {
        history.back()
        console.log(history.length)
        console.log(history.state)
    })
​
    // 实现前进一级路由
    var forwardEl = document.querySelector('.forward')
    farwordEl.addEventListener('click', function () {
        history.forward()
        console.log(history.length)
        console.log(history.state)
    })
</script>
</body>
</html>

BOM navigator 对象(使用得尊嘟很少很少)

就是用来实现的是表示我们用户代理的状态和标识的信息

就是实现的是帮助我们获取一些关于 浏览器的一些信息,比如说 user-agent

拓展:😄 😄 😄

首先在我们的印象中是不是只是只有我们的 python 可以用来实现爬虫???

可以肯定的是,可以用来实现爬虫的肯定不止有爬虫,还有其他的编程语言,那么可以用来爬虫的语言有那些特点耶???

  1. 可以对我们的服务端发送请求
  2. 对服务端返回的数据可以有一定程度上的解析以及保存能力
  3. 可以实现自动化运行

但是实际上的话,我们的爬虫最重要的一步就是进行网络请求,但是在请求的时候,可能设置代理,伪装

然后的话,这个 user-agent 字段就是用来发送请求的时候常用的伪装字段 😄

想知道有那些编程语言可以实现向服务端发送网络请求,最好的方法就是:

打开 postman | apifox | apipost, 可以实现向服务端发送请求的,这个里面应有尽有

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    console.log(navigator.userAgent)
    console.log(navigator.userActivation)
    console.log(navigator.serviceWorker)
    console.log(navigator.cookieEnabled)
</script>
</body>
</html>

BOM screen对象(也是很少用的)

就是实现得是获取硬件的屏幕信息

screen.width | screen.height 这个就是实现获取的是屏幕的逻辑像素

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    console.log(globalThis.screen.width)
    console.log(globalThis.screen.height)
</script>
</body>
</html>