总结:JavaScript进阶重点(DOM、BOM)

定义

  1. Dom
  • 文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理HTML/XML的标准API接口.
  • 提供对文档的结构化描述,定义方式对结构进行访问并进行修改结构,样式和内容
  • 顶级对象时是document
  1. Bom
  • 浏览器对象模型(Browser Object Model,简称BOM)
  • 提供了独立于内容而与浏览器窗口交互的对象
  • 顶级对象是window
  1. DOM和BOM的区别(对比图)
DOMBOM
文档对象模型浏览器对象模型
DOM把[文档]当做一个[对象]来看待BOM把[浏览器]当做一个[对象来看待
DOM的顶级对象是documentBOM的顶级对象是window
DOM主要学习的是操作页面元素BOM学习的是浏览器窗口交互的一些对象
DOM是W3C标准规范BOM是浏览器厂商在各自浏览器上定义的,兼容性差
  1. dom和bom的关系结构图
    在这里插入图片描述

一、DOM

1. dom树

在这里插入图片描述

  • 文档: 一个页面就是一个文档,DOM中使用document表示
  • 元素: 页面中的所有标签都是元素,DOM中使用element表示
  • 节点: 网页中的所有内容都是节点(标签,属性,文本,注释等),DOM中使用node表示

2. document对象

提示:


d o c u m e n t 对象对应整个文档 , 整个文档相关的操作和编程的 a p i 都是通过 d o c u m e n t 对象进行实现 \color{#000}{ document对象对应整个文档,整个文档相关的操作和编程的api都是通过document对象进行实现} document对象对应整个文档,整个文档相关的操作和编程的api都是通过document对象进行实现

2.1 常用属性
  • URL: 获取当前文档的URL地址,只读
document.URL
  • title: 获取当前文档Head中的title的文字内容,可写入修改
document.title
2.2 获取文档元素
 // 根据id,返回Element
getElementById('元素id')
//根据标签名获取(如果是*,返回所有),返回HTMLCollection集合
getElementsByTagName('标签名')
// 根据name属性,返回NodeList集合
getElementsByName(name) 
//根据元素类名返回元素对象集合
getElementByClassName('元素类名') 
// 根据css选择器返回第一个元素对象
querySelector('选择器') 
// 根据css选择器返回所有指定元素,多个选择器以逗号分隔querySelectorAll( 'p,a')
querySelectorAll('选择器') 
2.3 获取特殊元素(body,html)
// 获取body元素
const bodyElem = document.body;  //返回body元素对象
// 获取Html元素
const htmlElem = document.documentElement;  //返回html元素对象

3. 元素对象

3.1 Element
// Element对象是所有标签元素的基础对象,封装了所有标签元素的公共方法与属性
// 常用属性
Element.attributes				// 获得所有属性key-value集合
Element.className				// 获得类名(可读写)=>idea:elem.className = 'pink',然后再css定义
								// 注意:此方法会覆盖原有类名
============================^_^============================
Element.classList				// 返回一个元素的类属性的实时 DOMTokenList 集合(只读),通过其内部方法修改
								// ie10+,
============================^_^============================								
Element.id						// 获取元素id
Element.innerHTML				// 获取元素内部包裹的html标签字符串(可读写)
Element.innerText				// 获取元素内部文本,标签不识别会直接进行显示(可读写)
Element.tagName					// (只读)获取元素的标签名字符串
Element.style					// 获取/修改style样式,如Element.style.backgroundColor


// 常用方法
Element.getAttribute(attrName)		// 返回属性的字符串值,适合获取自定义属性data-
Element.removeAttribute(attrName)	// 从指定的元素中删除一个属性
Element.setAttribute(attrName,value)// 设置属性
Element.hasAttribute(attrName)		// 检测属性是否存在
Element.getElementsByClassName()	// 获取后代元素根据className
Element.getElementsByTagName()		// 获取后代元素根据tagName
...

Element.dataset.index | Element.dataset['index']  // 用于获取data-自定义属性(h5新增),支持驼峰命名获取(ie11+)
3.2 HTMLCollection
// HTMLCollection对象,是伪数组。元素的动态集合,提供了用来从该集合选择元素的方法和属性,当其所包含的文档结构发生改变时,会自动更新.
// 常用属性
HTMLCollection.length 		// 返回集合中子元素的数组

============================^_^============================		

// 常用方法
HTMLCollection.item()		// 根据给定的索引(从0开始),返回具体的节点
HTMLCollection.namedItem() 	// 根据 Id 返回指定节点,或者作为备用,根据字符串所表示的 name 属性来匹配

4. 节点操作

WARNING:


一般的 , 节点至少拥有 n o d e T y p e ( 节点类型 ) , n o d e N a m e ( 节点名称 ) , n o d e V a l u e ( 节点值 ) \color{#000}{ 一般的,节点至少拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)} 一般的,节点至少拥有nodeType(节点类型),nodeName(节点名称),nodeValue(节点值)

  • 元素节点 nodeType为1
  • 属性节点 nodeType为2
  • 文本节点 nodeType为3(文本几点包含文字,空格,换行等)
4.1 节点层级
  • 父级节点
    //parentNode属性可返回某节点的父节点,注意是最近的一个父节点(亲爸爸)
    node.parentNode // 找不到返回null
  • 子节点
parentNode.childNodes 			// 注意: 会返回3种子节点=>如果指向某种节点,可通过nodeType判断
parentNode.firstChild			// 返回第一个子节点(会包括3种节点)
parentNode.lastChild			// 获取最后一个子节点(会包括3种节点)

parentNode.children				// 只获取子元素节点
parentNode.firstElementChild	// 获取第一个子元素节点(ie9+)
parentNode.lastElementChild		// 获取最后一个子元素节点(ie9+)

*注意:
parentNode.childNodes 返回值里包含了所有子节点,包括元素节点,文本节点等

  • 兄弟节点
node.nextSibling				// 当前元素的下一个兄弟节点(会包含3种节点)
node.previousSibling			// 当前元素的上一个兄弟节点(会包含3种节点)

node.nextElementSibling			// 当前元素的下一个兄弟元素节点(IE9+)
node.previousElementSibling		// 当前元素的上一个兄弟元素节点(IE9+)
  • 节点创建与添加
// 创建节点
let li = document.createElement('li');
// 在已有子节点后面追加节点(不会覆盖原有节点)
parentNode.appendChild(li);
// 在指定子节点前面追加节点(不会覆盖原有节点)
parentNode.insertBefore(child,指定子元素)
  • 节点移除
parentNode.removeChild(child节点)		// 删除父元素的某个子节点
  • 节点复制
node.cloneNode()	// 拷贝node节点=>浅拷贝,只拷贝标签,不拷贝里面内容
node.cloneNode(true)// 拷贝node节点=>深度拷贝,拷贝标签以及里面内容
  • 三种动态创建元素的区别
document.write('<div>123</div>')  		// 注意:当页面文档流加载完毕,会进行重绘
element.innerHTML = '<div>123</div>'	// 不要重复拼接字符串,内存消耗过大
document.createElement()				

5.DOM事件

5.1 鼠标事件
鼠标事件触发条件
onclick鼠标点击左键触发
onmouseover鼠标经过触发
onmouseout鼠标离开触发
onfocus获得鼠标焦点触发
onblur失去鼠标焦点触发
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发
oncontextmenu阻止鼠标右键菜单(阻止默认行为)
onselectstart禁止鼠标选取内容(阻止默认行为)
onselect禁止复制(阻止默认行为)
  • mouseenter和mouseover区别

mouseover经过自身会触发,经过子级也会再次触发(支持事件冒泡).mouseenter只有经过自身盒子才触发(不支持事件冒泡)

备注:mouseover搭配mouseout;mouseenter搭配mouseleave

5.2 键盘事件

三个事件的执行顺序: keydown > keypress > keyup

键盘事件触发条件
keyup某个键盘按键松开触发
keydown某个键盘按键按下时触发,只要不松开会一直触发
keypress某个键盘按键按下时触发,不识别功能键(ctrl,上下箭头等),只要不松开会一直触发
在这里插入图片描述
5.3 注册事件

注:注册事件有两种方式:传统方式和监听方式

  • 传统方式: 使用on前缀 => 事件注册具有唯一性,后者会覆盖前者
<p onclick="alert(123)">
  点击  
</p>
//最后只能弹出来"点击段落"的弹框,后者覆盖了前者
const elem = document.querySelector('p')
elem.onclick = function() {
    alert('点击段落');
}

// 解绑事件
elem.onclick = null
  • 监听方式
// true:事件句柄在捕获阶段执行 false(默认):事件句柄在冒泡阶段执行
// 注意:解除绑定与绑定的事件内存地址需要相同
let div = document.getElementById('div')
function listener(event) {
    
}
div.addEventListener('click',listener,true)
div.removeEventListener('click',listener,true)

// ie9以前使用attachEvent,处理兼容性再用吧
div.attachEvent('onclick',method) // 绑定
div.detachEvent('onclick',method) // 移除

在这里插入图片描述

5.4 触屏事件对象(touchEvent)

touchEvent是一类描述手指在触摸平面(触摸屏等)的状态变化的事件对象,这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少等

touchEvent对象说明
event.touches正在触摸屏幕的所有手指的一个列表(可判断双指还是单指触屏)
event.targetTouches正在触摸当前dom元素上的手指的一个列表
event.changedTouches手指状态发生了改变的列表,从无到有,从有到无变化
5.5 事件流

事件分为捕获阶段与冒泡阶段.捕获阶段就是事件信息从顶层向下层传递的过程,冒泡时事件反应处理从底层向上层反馈的过程。

在这里插入图片描述
js可以通过addEventListener来实现捕获阶段或者冒泡阶段的事件响应方法注册

5.6 事件对象
  • 什么是事件对象
    在这里插入图片描述

事件对象鼠标事件(MouseEvent),则记录鼠标相关信息,如坐标等;键盘事件(KeyboardEvent),则记录键盘相关信息,如点击的哪个按键

elem.onclick = function(event) { // 此处的event就是事件对象
    event.target 				 // 返回触发事件的元素,不同于this返回的是绑定事件的元素
    event.srcElement			 // 同event.target,ie兼容处理使用(ie6,7,8),非标准
    event.relatedTarget			 // 返回绑定事件的元素,类似于this
    event.type					 // 获取事件触发类型,如click、mouseover,不带on
    event.pageX | event.pageY	 // 获取光标相对于页面的x坐标和y坐标 ie9+
    event.clientX | event.clientY// 获取光标相对可视区域的x坐标与y坐标(不受滚动条影响)
    event.screenX | event.screenY// 获取光标相对电脑屏幕的x坐标与y坐标
    event.which					 // 代表获取到的鼠标或键盘的输出的值,鼠标分别为0,1,2
    event.key					 // 获取按下的按键值
    event.keyCode				 // 获取按下按键的ascii码值
}
5.7 默认行为与冒泡阻止
  • 常见html默认行为
~ Submit按钮: 在form表单中的,提交form表单中的数据到服务器
~ Button: 在手机浏览器中, 若是在form中,则是submit
~ a标签: 默认将当前页面跳转为a标签中href的地址
  • 阻止事件默认行为
<!-- 方式4 -->
<a onclick="javascript:;">点击</a>
<script>
	const a = document.querySelector('a');
    a.onclick = function(event) {
        // 方式1
        event.preventDefault()
        // 方式2,低版本ie使用
        event.returnValue()
        // 方式3,addEventListener注册方式无效
        return false 
    }
</script>
  • 阻止冒泡
<div class="parent">
    <div class="child"></div>
</div>
<script>
	const pElem = document.querySelector('.parent')
    const cElem = document.querySelector('.child')
    cElem.onclick = function(event) {
        // 标准: 阻止冒泡
        event.stopPropagation()
        // 非标准: 阻止冒泡(ie678)
        event.cancalBabel = true
    }
</script>

兼容性写法:
在这里插入图片描述

5.8 事件委托

事件委托又叫事件代理,jquery里面称为事件委派

  • 原理: 不再每个子节点单独设置事件监听器(提高了性能),而是将事件监听器设置再父级元素上,然后利用冒泡原理影响每个子节点
    在这里插入图片描述
<ul>
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>

<script>
    const ul = document.querySelector('ul');
    ul.addEventListener('click', event => {
        // 不用单独每个li绑定事件
        //event.target可以得到我们点击的对象
        console.log(event.target);
    });
</script>

二、BOM

BOM没有标准组织,ECMA有ECMA组织,DOM有W3C组织制定,而BOM还是在延用网景的标准,兼容较差

  • 它是js访问浏览器窗口的一个接口
  • 它是一个全局对象,定义在全局作用域的变量,函数都会变成window对象的属性和方法 => this指向问题产生

1. Window对象

1.1 属性
window.innerWidth	// 获取当前屏幕宽度,tip 可用来做响应式布局,还是推荐媒体查询,flex做响应式布局
window.innerHeight	// 获取当前屏幕高度
1.2 方法
window.scroll(x,y)	// 滚动窗口至文档中的特定位置 => such: window.scroll(0,0) 滚动到页面顶部
1.3 事件
  • 窗口加载事件
window.onload = function() {}
// 或
window.addEventListener('load',function() {})

// window.onload是窗口加载事件,当文档内容完全加载会触发该事件(包括图像,脚本文件,css文件等)
// window.onload传统注册事件只能写一次,如果多次会以最后一个为准,addEventListener没有此问题

window.addEventListener('DOMContentLoaded',function(){}) // 只要dom文档加载完就会触发监听事件
  • 窗口大小调整事件
// 窗口大小发生变化,就会触发
window.onresize = function() {}
window.addEventListener('resize',function() {})

2. location对象

2.1 属性
location对象属性返回值
location.href获取或设置整个URL
location.host返回主机域名
location.port返回端口号
location.pathname返回路径
location.search返回参数
location.hash返回锚点
2.2 方法
location.assign()		// 跟href相同,实现跳转页面
location.replace()		// 替换当前页面,因为不记录历史,所以不能后退页面
location.reload()		// 重新加载页面,参数为true会强制刷新
2.3 URL(同一资源定位符)

url的一般语法格式为:
protocol://host[:port]/path/[?jquery]#fragment
https://www.baidu.com/index.html?name=andy&age=18#link
在这里插入图片描述

组成说明
protocol通信协议,如http,https,ftp,maito
host主机(域名)
port端口(默认80)
path资源路径;由零或多个"/"隔开的字符串
query参数,以键值对形式,通过&符来隔开
fragment锚点;#后面内容

3. navigator对象

navigator对象包含了很多设备相关属性例如操作系统,版本号等信息
在这里插入图片描述

// case: 使用userAgent识别手机pc
if(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {
    window.location.href = ''; //手机
} else {
    window.location.href = ''; //电脑
}

4. history对象

window对象为我们提供了一个history对象,与浏览器历史记录进行交互,该对象包含用户(在浏览器窗口中)访问过的URL

history对象方法作用
back()实现后退
forward()实现前进
go(参数)前进后退功能,参数是1: 前进一个页面,-1:后退一个页面

5. 定时器

  • setInterval(重复执行,每次调用有时间延迟)
let inervalId = setInterval(code, milliseconds);
let inervalId = setInterval(function, milliseconds, param1, param2, ...)
  • setTimeOut(只执行一次,延迟delay毫秒后执行)
let interValId = setTimeOut(fn,delay)
  • 清除延迟
clearInterVal(inervalId)	 // 对应setInterval
clearTimeOut(inervalId)		 // 对应setTimeOut
  • 标题跑马灯效果实现
// 数组方式实现跑马灯效果
setInterval(() => {
    let title = [...document.title];
    title.unshift(title.pop());
    document.title = title.join('');
}, 500);

// 字符串方式实现跑马灯
setInterval(() => {
    let oldTitle = document.title;
    let newTitle = oldTitle.slice(-1).concat(oldTitle.slice(0, -1));
    document.title = newTitle;
}, 500);

6. JS执行机制

6.1 JS是单线程

javascript就是为了处理页面中用户的交互以及操作DOM而产生,js是单线程 => 这就意味着所有任务都需要排队,前一个任务执行结束才能执行下一个任务。导致某个js流程执行时间过长,页面渲染就不连贯,造成页面阻塞

6.2 同步和异步

为了解决js的单线程阻塞问题,利用多核CPU的计算能力,HTML5提出Web Worker标准,允许Javascript脚本创建多个线程。

  • 同步: 前一个任务执行完毕才进行下一任务

    注意: 同步任务都在主线程上执行,形成一个执行栈
    
  • 异步: 前一任务执行过程种,同时执行另一任务

    JS的异步任务都是通过回调函数来处理,如监听事件,点击事件等
    
6.3 执行机制
  • 先执行执行栈的同步任务
  • 异步任务(回调函数)放到任务队列中
  • 一旦执行栈中的同步任务执行完毕,系统就会依次执行任务队列中的异步任务
    在这里插入图片描述

三、网页特效

1. 元素偏移量offset

使用offset相关属性,可以动态获取该元素的位置(偏移),大小等.

  • 注意: 返回值是不带单位的
  • 获得元素距离带有定位父元素的位置
  • 获取元素自身大小(宽度和高度)
offset系列属性作用
element.offsetParent返回该元素带有定位的父级元素,如何父级都没有定位返回body
element.offsetTop返回元素相对带有定位父元素上方的偏移
element.offsetLeft返回元素相对带有定位父元素左边框的偏移
element.offsetWidth返回自身包括内边距,边框,内容区的宽度 => border+padding+width
element.offsetHeight返回自身包括内边距,边框,内容区的高度=> border+padding+width
  • offset与style区别(宽度)
offsetstyle
offset可以得到任意样式表中的样式值只能得到行内样式表的样式值,css中的获取不到
获得的数值没有单位获得的是有单位的字符串
offsetWidth包含padding+border+widthstyle.width不包含padding和border
offsetWidth只读style.width可读写
适合获取元素大小位置适合修改元素值

2. 元素可视区client

通过client的相关属性可以动态获取该元素的边框大小,元素大小等

  • 注意: 返回值是不带单位的
client作用
element.clientTop返回元素上边框的大小
element.clientLeft返回元素左边框的大小
element.clientWidth返回自身包括padding,内容区宽度,不包含边框
element.clientHeight返回自身包括padding,内容区高度,不包含边框

3. 元素滚动scroll

通过scroll可以动态获取该元素的大小,滚动距离等

  • 注意: 返回值是不带单位的
scroll作用
element.scrollTop返回被卷去的上侧距离
element.scrollLeft返回被卷去的左侧距离
element.scrollWidth返回自身实际的宽度,不含边框,包含padding
element.scrollHeight返回自身实际的高度,不含边框,包含padding

注意: 页面的滚动距离通过window.pageXOffset获取

四、动画

1.封装动画函数

 (function () {
        function animate(obj, target, comeback) {
          //让我们只有一个定时器执行
          //先清除以前的定时器,只保留当前的一个定时器执行
          clearInterval(obj.timer);
          obj.timer = setInterval(function () {
            //步长值写到定时器里
            //var step=Math.ceil((target-obj.offsetLeft)/10);
            varstep = (target - obj.offsetLeft) / 10;
            step = step > 0 ? Math.ceil(step) : Math.floor(step);
            if (obj.offsetLeft == target) {
              //停止动画本质是停止定时器
              clearInterval(obj.timer);
              //回调函数写到定时器结束里面
              //if(comeback){
              //comeback();
              //}
              comeback && comeback();
            }
            //这个步长值改为一个慢慢变小的值步长公式:(目标值-现在的位置)/10
            obj.style.left = obj.offsetLeft + step + "px";
          }, 15);
        }
      });

2. 缓动动画

在这里插入图片描述

五、本地存储

本地存储特性:

  • 数据存储在用户浏览器中
  • 设置,读取方便,甚至页面刷新不丢失数据
  • 容量较大,sessionStorage约5M,localStorage约20M
  • 只能存储字符串,对象转json后再存储

1. window.sessionStroage

  • 生命周期为关闭浏览器窗口
  • 在同一窗口(页面)下数据可以共享
  • 以键值对的形式存储使用
const user = { name: '隔壁老高', age: 18 }

// sessionStorage
// 存储数据
sessionStorage.setItem('user', JSON.stringify(user, null, 2))
// 修改数据 => 重新存储即可
// 读取数据
sessionStorage.getItem('user')
// 删除数据
sessionStorage.removeItem('user')
// 清空数据
sessionStorage.clear()

2. window.localStorage

  • 生命周期永久生效,除非手动删除否则关闭页面也会存在
  • 可以多窗口(页面)共享(同一浏览器可以共享数据)
  • 以键值对的形式存储使用
const user = { name: '隔壁老高', age: 18 }

// localStorage
// 存储数据
localStorage.setItem('user', JSON.stringify(user, null, 2))
// 修改数据 => 重新存储即可
// 读取数据
localStorage.getItem('user')
// 删除数据
localStorage.removeItem('user')
// 清空数据
localStorage.clear()

~有问题可以评论区留言,喜欢的小伙伴可以点赞、关注、收藏哦 ♥♥♥ \color{red}{♥♥♥} ♥♥♥

相关推荐:wantLG的《普歌-码上鸿鹄团队复习总结:js 高级 ECMAScript 6(es6新特性)(上)


  • 作者:wantLG
  • 本文源自:wantLG的《普歌-码上鸿鹄JavaScript进阶(BOM、DOM)总结
  • 本文版权归作者和CSDN共有,欢迎转载,且在文章页面明显位置给出原文链接,未经作者同意必须保留此段声明,否则保留追究法律责任的权利。
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wantLG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值