什么你还不会BOM和DOM,看这个??本文总结:BOM和DOM相关操作、如何使用DOM控制CSS样式、如何写入节点、事件基础内容 
下面介绍BOM与DOM的相关操作

BOM 即浏览器对象模型(Browser Object Model),它提供了页面与浏览器窗口进行交互的对象接口。BOM 由一系列的相关对象组成,window 作为 BOM 的顶层对象,所有其他全局对象都是 window 的子对象,甚至 DOM 也是其子对象之一;
window 对象作为 BOM 的顶级对象,本身包含一些全局属性和方法,其子对象也有其
特有的属性和方法
使用 window 子对象时,可以使用完整语法,也可以忽略 window,如:window.alert()
与 alert()效果相同
| 方法 | 说明 |
|---|---|
| open() | 打开一个新的浏览器窗口 |
| alert() | 显示警告窗口 |
| close() | 关闭当前浏览器窗口 |
| scrollTo() | 可把内容滑动到指定坐标 |
| scrollBy() | 可将内容滑动指定的距离(相对于当前位置) |
| innerWidth | 返回窗口的网页显示区域宽度 |
| innerHeight | 返回窗口的网页显示区域高度 |
| 参数 | 说明 |
|---|---|
| url | 打开指定页面的 url,如果没有则打开空白页 |
| name | 指定 target 属性或窗口名称,支持以下值:_blank 加载到新窗口(默认)_parent 加载到父框架_self 替换当前页面_top 替换任何可加载的框架集 |
| features | 设置新打开窗口的功能样式(如:width=500) |
| replace | true – 替换浏览历史中的当前条目 false – 在浏览历史中创建新条目 |
//新窗口打开Hammer博客open('https://www.cnblogs.com/48xz/p/15887331.html')//当前窗口打开Hammer博客open('https://www.cnblogs.com/48xz/p/15887331.html','_self')//新窗口打开csdn窗口,设置窗口大小open('https://www.cnblogs.com/48xz/p/15887331.html','_self','width=500,height=500')location 对象包含当前 url 信息,经常用于网址判断,url 跳转
| 方法 | 说明 | 示例 |
|---|---|---|
| href | 返回当前完整网站 | location.href |
| host | 返回主机名和端口号,通常指完整域名 | location.host |
| protocol | 返回网址协议 | location.protocol |
| port | 返回端口号 | location.port |
| pathname | 返回网址路径部分 | location.pathname |
| search | 返回网址?后的字符串(查询部分),通常指所有参数 | location.search |
| hash | 返回网址#后的字符串,通常指锚点名称 | location.hash |
| assign(url) | 在当前页面打开指定新url(增加浏览记录) | location.assign('https://www.cnblogs.com/48xz/') |
history 对象包含用户浏览器的历史记录,但是不可读取,经常用于页面跳转
| 方法 | 说明 | 示例 |
|---|---|---|
| back() | 返回历史记录的上一个url | history.back() |
| forward() | 返回历史记录的下一个url | history.forward() |
| go(n) | 返回相对于当前记录的第 n 个 url n>0,表前进;n<0,表后退; n=0,刷新当前页 | history.go(-1) history.go(1) history.go(0) |
navigator 对象包含浏览器相关信息,经常用于判断设备类型,浏览器兼容性
| 方法 | 说明 | 示例 |
|---|---|---|
| platform | 返回操作系统类型 | navigator.platform |
| userAgent | 返回用户代理头的值 | navigator.userAgent |
navigator.platform//'Win32'navigator.userAgent//'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36'screen 对象包含用户屏幕的信息
| 方法 | 说明 |
|---|---|
| availWidth | 返回屏幕的宽度(不包括 windows 任务栏) |
| availHeight | 返回屏幕的高度(不包括 windows 任务栏) |
| width | 返回屏幕的总宽度 |
| height | 返回屏幕的总高度 |
screen.availHeight//824screen.availWidth//1536screen.width//1536screen.height//86| 方法 | 说明 | 清除定时器方法 |
|---|---|---|
| setTimeout() | 指定的毫秒数后调用函数或计算表达式 | clearTimeout() |
| setInterval() | 按照指定的周期(毫秒)来调用函数或计算表达式 | clearInterval() |
示例
格式:var t=setTimeout("JS语句",毫秒) setInterval("JS语句",时间间隔)// 在指定时间之后执行一次相应函数var timer = setTimeout(function(){alert(123);}, 2000)// 取消setTimeout设置clearTimeout(timer);// 每隔一段时间就执行一次相应函数var timer = setInterval(function(){alert(123);}, 2000)// 取消setInterval设置clearInterval(timer);setTimeout()案例
<p ></p> <button >清除定时器</button> <script> var info = document.querySelector('.info') var btn = document.querySelector('.btn') var t1 = setTimeout(function() { info.innerHTML = '已经 5 秒了' }, 5000); // 点击按钮可清除定时器 var btn = document.querySelector('.btn') btn.addEventListener('click', function() { clearTimeout(t1) info.innerHTML = '定时器已清除' })</script>示例
<p ></p> <script> var info = document.querySelector('.info') var num = 0 var t1 = setInterval(function() { // 每隔 1 秒显示当前时间,5 次后停止 info.innerHTML = '当前时间:' + String(new Date()) if (num >= 4) { clear() } num++ }, 1000) // 清除定时器 function clear() { clearInterval(t1) info.innerHTML = '定时器已清除' } </script>在JS中有三种弹框:警告框、确认框、提示框
alert(“警告框”)confirm("确认框") -----如果用户点击确认,那么返回值为 true。如果用户点击取消,那么返回值为 false;prompt("请在下方输入","输入内容") -----提示框经常用于提示用户在进入页面前输入某个值,然后确认才能继续操作,如果确认返回输入的值,点击取消返回值为nullDOM(Document Object Model——文档对象模型)是用来处理 HTML 和 XML 的 跨平台 API。它允许运行在浏览器中的代码访问文档节点并与之交互,了解并掌握 DOM 操 作是 Web 开发中的必经之路

整个 HTML 的结构都可以由类似上图的树结构表示,整个树结构由节点组成
| 节点 | 说明 |
|---|---|
| 文档节点(document对象) | 代表整个文档节点 |
| 元素节点(element对象) | 代表一个元素(标签) |
| 文本节点(text对象) | 代表元素(标签)中的文本 |
| 属性节点(attribute对象) | 代表一个属性,元素(标签)才有属性 |
| 注释节点(comment对象) | 注释 |
document对象指代整个文档节点,他是文档内其他节点的访问入口,提供操作其他节点的方法
节点的分类:元素节点、文本节点、属性节点
节点之间的层级关系:父(parent)、子(child)和同胞(sibling)等术语用 于描述这些关系。父节点拥有子节点,同级的子节点被称为同胞(兄弟或姐妹)
要进行 DOM 操作,首先要获取到需要操作的节点或节点集合,接下来以下面的示例代码为基础,介绍常用的 DOM 获取方法和属性;
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>DOM</title></head><body><div id="container"> <p title="111">项目 1</p> <p >项目 2</p> <p>项目 3</p> <input type="text" value="123"> <!--默认值123--></div></body></html>
| 方法 | 说明 |
|---|---|
| getElementById | 获取带有指定id的节点 |
| getElementsByTagName() | 获取带有指定标签名的节点集合 |
| getElementsByClassName() | 获取带有指定类名的节点集合 |
| querySelector() | 获取指定选择器或选择器组匹配的第一个节点 |
| querySelectorAll() | 获取指定选择器或选择器组匹配的所有节点集合 |
getElementById案例
//获取 id 为 container 的节点document.getElementById('container')
getElementsByTagName()案例
document.getElementsByTagName('p')
document.getElementsByTagName('p')[0]
getElementsByClassName()案例
document.getElementsByClassName('box')
document.getElementsByClassName('box')[0]
querySelector()代码示例
//获取被选择器'.box .item'匹配的第一个节点document.querySelector('.box .item')//获取选择器'div'(标签)匹配的节点document.querySelector('div')

querySelectorAll()示例
document.querySelectorAll('.item')[0]document.querySelectorAll('.item')[1]
| 方法 | 说明 |
|---|---|
| innerHTML | 返回元素内包含的所有 HTML 内容(文本和标签),类型为字符串 |
| innerText | 和innerHTML类似,但是只返回文本 |
| children | 返回指定元素的子元素节点集合 |
| parentNode | 返回指定节点的父节点 |
| firstElementChild | 返回指定元素的第一个子元素节点 |
| lastElementChild | 返回指定元素的最后一个子元素节点 |
innerHTML和innerText示例
document.querySelector('.box').innerTextdocument.querySelector('.box').innerHTML
children和parentNode示例
document.querySelector('.item').parentNodedocument.querySelector('.box').children[0]
firstElementChild和lastElementChild示例
document.querySelector('.box').firstElementChild.innerTextdocument.querySelector('.box').lastElementChild.value
| 方法 | 说明 |
|---|---|
| getAttribute() | 返回元素一个指定的属性值 |
| 直接使用属性名称获取 | 适用于部分属性(如:title,value,href) |
document.querySelector('.box .item').getAttribute('title')document.querySelector('input').getAttribute('value')document.querySelector('input').valuedocument.querySelector('.box .item').title 
上面介绍的是DOM获取方法和属性,下面介绍如何交互,主要用到修改、删除、添加
| 方法 | 说明 |
|---|---|
| innerHTML | innerHTML 除了获取元素内容,也可通过赋值用于修改元素中内容。 如果修改内容中包含 html 字符串会被解析成 html元素; |
| setAttribute(name,value) | 设置指定元素上的某个属性值。如果属性已经存在,则更 新该值;否则,使用指定的名称和值添加一个新的属性; |
JS示例代码
<div id="container"> <p title="111">项目 1</p> <p >项目 2</p> <p>项目 3</p> <input type="text" value="123"></div>innerHTML示例
// 更改为文字document.querySelector('.box .item').innerHTML = '项目A'// 更改为 html 内容(p 元素中内容替换为 span 元素)document.querySelector('p').innerHTML = '<span>简易示例</span>'

setAttribute(name, value)代码示例
//参数:name 为属性名,value 为属性值//将第一个p元素节点的title属性值修改document.querySelector('p').setAttribute('title','one')
| 方法 | 说明 |
|---|---|
| createElement(tagName) | 创建一个由标签名称 tagName 指定的 HTML元素(标签) |
| appendChild(node) | 将一个节点插入到指定父节点的子节点列表的末尾 |
| insertAdjacentHTML(position, text) | 将指定文本解析为 HTML 字符串,插入到指定位置 |
createElement(tagName)示例
newDiv = document.createElement('div')// 可以直接对创建完的元素进行操作newDiv.innerHTML = '新添加的元素'
appendChild(node)示例
var p = document.createElement('p')document.querySelector('div').appendChild(p)p.innerHTML='追加在尾部的p'
insertAdjacentHTML(position, text)示例
| position位置参数 | 说明 |
|---|---|
| 'beforebegin’ | 元素自身的前面 |
| 'afterbegin‘ | 插入元素内部的第一个子节点之前 |
| 'beforeend' | 插入元素内部的最后一个子节点之后 |
| 'afterend' | 元素自身的后面 |
示例
<!--html代码--><div> <p>元素1</p> <p>元素2</p></div>
var div = document.querySelector('div')div.insertAdjacentHTML('beforebegin','<p>元素自身前面</p>')div.insertAdjacentHTML('afterbegin','<p>元素1前面</p>')div.insertAdjacentHTML('beforeend','<p>元素2后面</p>')div.insertAdjacentHTML('afterend','<p>元素自身后面</p>')
删除选定的子节点,需要指定父元素
// html 结构如下:<div> <p>元素1</p> <p>元素2</p></div> <script> // 删除 div 中的第一个 p 元素 var parent = document.querySelector('div') var child = document.querySelector('p') parent.removeChild(child)</script>style 属性可以设置或返回元素的内联样式
“-”,则需转换为小驼峰形式,如:backgroundColor,marginLeft;var box = document.querySelector('div') box.style.color = "#fff" // 将元素中文字设置为白色 box.style.marginLeft = "100px" // 将元素左外边距设置为 100pxclassList 属性返回一个元素类属性集合(这里可以简单理解为类名的集合),通过使 用 classList 中的方法可以方便的访问和控制元素类名,达到控制样式的目的
classList 常用方法:
| 方法 | 说明 |
|---|---|
| add(class1, class2, …) | 添加一个或多个类名 |
| remove(class1, class2, …) | 移除一个或多个类名 |
| replace(oldClass, newClass) | 替换类名 |
| contains(class) | 判定类名是否存在,返回布尔值 |
| toggle(class, true|false) | 如果类名存在,则移除它,否则添加它 第二个参数代表无论类名是否存在,强制 添加(true)或删除(false) |
<div >classList test</div><script> var box = document.querySelector('.box') box.classList.add('box1', 'box2') // [box] => [box, box1, box2] box.classList.remove('box1', 'box2') // [box, box1, box2] => [box] box.classList.replace('box', 'box2') // [box] => [box2] box.classList.contains('box1') // 当前元素不包含类名 box1,返回 false box.classList.toggle('active') // [box2] => [box2, active] </script>当我们需要更改一个标签的文字或内容时,这时就需要了解节点写入的知识,学会节点写入可以帮助我们更加精确的控制网页内容,节点写入的方式有很多种,这里介绍常用的几种方法:
| 方法 | 说明 |
|---|---|
| innerHTML | 返回元素中的 html 内容,通过赋值,可设置元素中的 html 内容 |
| innerText | 返回元素中的文本内容,通过赋值,可设置元素中的文本内容 |
| document.write() | 将 html 字符串写入到文档中 |
innerHTML
<!--在 div 中写入 h1 标签,如果原来div中有内容会被覆盖--><body> <div></div> </body> <script> document.querySelector('div').innerHTML = '<h1>我是新内容</h1>' </script>
innerText
<body> <div></div> </body> <script> document.querySelector('div').innerText = '<h1>我是新内容</h1>' </script>
document.write()
document.write('我是新内容')document.write('<h1>我是新内容</h1>')和 innerHTML 类似,写入内容如果包含 html 标签字符串,会被解析成对应的 html 标签,document.write()根据运行时机,会写入文档不同的位置

事件绑定就是事件源与事件绑定之后,才能触发对应事件
var btn = document.querySelector('button'); btn.onclick = function() { alert('事件属性赋值') }<button onclick="alert('行内事件属性赋值')">点击按钮</button>格式:addEventListener(type, listener, useCapture)type:事件类型listener: 监听器(处理程序)useCapture: 默认为 false,设置为 true 时,不会因冒泡触发监听器const btn = document.querySelector('button'); btn.addEventListener('click', function() { alert('事件监听') })| 方法 | 说明 |
|---|---|
| click | 单击鼠标左键触发。焦点在按钮并按了 Enter 键时,也会触发 |
| contextmenu | 右键点击(右键菜单显示前触发) |
| dblclick | 双击左键触发 |
| mouseenter | 指针移至元素范围内触发一次 |
| mouseleave | 指针移出元素范围外触发一次 |
| mouseover | 指针移至元素或其子元素内,可能触发多次 |
| mouseout | 指针移出元素,或者移至其子元素内,可能触发多次 |
ps:事件处理程序中的 this 指代当前操作元素
示例
var btn = document.querySelector('button') btn.addEventListener('mouseenter', function() { // 鼠标移入文字为红色 this.style.color = 'red' })btn.addEventListener('click', function() { // 鼠标单击文字为蓝色 this.style.color = 'blue' })btn.addEventListener('mouseleave', function() { // 鼠标移出文字为黑色 this.style.color = 'black' })
| 方法 | 说明 |
|---|---|
| keydown | 按下任意按键,按住可连续触发 |
| keypress | 按下按键(包括字母,文字和 Enter)触发,按住可连续触发,不能监听一些特殊按键(ALT、CTRL、SHIFT、ESC、方向键等) |
| keyup | 释放任意按键 |
ps:键盘事件经常用于表单元素中,如:input 输入框
示例
var input = document.querySelector('input') input.addEventListener('keydown', function() { console.log('keyup', this.value) // 获取上一次输入值})input.addEventListener('keypress', function() { console.log('keypress', this.value) // 获取上一次输入值 })input.addEventListener('keyup', function() { console.log('keydown', this.value) // 获取当前输入值 })keydown->keypress->keyup),不同的键盘事件触发时机不 同,返回的结果有区别使用键盘事件属性可以精确的控制键盘操作,如:回车触发,方向键触发
| 方法 | 说明 |
|---|---|
| keyCode | keyCode 属性返回 keypress 事件触发的键的值的字符代码,或者keydown 或 keyup 事件的键盘代码 |
| 方法 | 说明 |
|---|---|
| charCode | 返回 keypress 事件触发时按下的字符键的字符 Unicode 值,用于 |
| key | 返回按键的标识符(字母区分大小写)。keypress,keyup,keydown |
示例
// 以输入 a 为例,分别查看三种事件返回结果 var input = document.querySelector('input') input.addEventListener('keydown', function(event) { console.log(event.keyCode) // 65 console.log(event.charCode) // 0 console.log(event.key) // a})input.addEventListener('keypress', function(event) { console.log(event.keyCode) // 97 console.log(event.charCode) // 97 console.log(event.key) // a })input.addEventListener('keyup', function(event) { console.log(event.keyCode) // 65 console.log(event.charCode) // 0 console.log(event.key) // a })可以看到,三种事件中,只有 key 属性返回的结果保持统一,如果不考虑 IE8 以下浏览器兼容性,推荐使用 key 来代替 keyCode 和 charCode
窗口事件在浏览器窗口发生变化时触发,其中包括窗口大小更改,加载窗口,关闭窗口,窗口滚动等,掌握如何处理窗口事件可以帮助我们实现更加丰富的交互效果;
| 方法 | 说明 |
|---|---|
| load | 当整个页面及所有依赖资源(如样式表和图片)都已完成加载时,将触发load事件 |
| beforeunload | window、document 和它们的资源即将卸载时触发。当事件属性returnValue 被赋值为非空字符串时,会弹出一个对话框,让用户确认是否离开页面。否则,事件被静默处理。一些浏览器实现仅在框架或内置框架接收到用户手势或交互时才显示对话框 |
| resize | 窗口大小改变时触发 |
| scroll | 元素内发生滚动时触发 |
load事件示例
<script> /* 输出 div 中文字内容 */ // 方式一 window.addEventListener('load', function() { console.log(document.querySelector('.box').innerHTML) }) // 方式二 window.onload = function() { console.log(document.querySelector('.box').innerHTML) }</script> <div >主要内容</div>beforeunload 事件代码示例
window.addEventListener("beforeunload", function (e) { var confirmationMessage = "confirm close window ?" //兼容 WebKit 与非 WebKit 内核浏览器 (e || window.event).returnValue = confirmationMessage return confirmationMessage })resize 事件代码示例
多用于检测不同屏幕尺寸,自适应布局
/* 调整浏览器窗口时,获取可视窗口宽高 */ window.addEventListener("resize", function (e) { console.log(window.innerWidth) // 可视窗口宽 console.log(window.innerHeight) // 可视窗口高 })scroll 事件代码示例
常用于检测滚动条滚动距离
/* 获取滚动条垂直滚动距离 */ window.addEventListener("scroll", function () { var scrollTop= window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; // 兼容写法 console.log(scrollTop); })