DOM (Document Object Model 文档对象模型)
一、介绍
1. dom 选择器, 节点类型
document
表示整个文档-
.getElementById()
.getElementsByTagName()
类数组.getElementsByClassName()
类数组.querySelector()
类数组.querySelectorAll()
类数组
- 节点类型
- 元素节点 1
- 属性节点 2
- 文本节点 3
- 注释节点 8
- document 9
- DocumentFragment 11
2. dom 继承树,dom 基本操作
- dom 继承树
document -> HTMLDocument{ __propto__: Document.prototype} -> Document.prototype
Node
Doucument
- HTMLDocument
- Element
- HTMLElement
- - HTMLHeadElementHTMLBodyElement,
- - HTMLHeadElement
- - HTMLTitleElement,...etc
- CharacterData
- Text
- Comment
dom
基本操作-
查
- 遍历节点树
parentNode
childNodes
子节点firstNode
lastNode
nextSibling
后一个兄弟节点previousSibling
前一个兄弟节点
- 遍历元素节点树
parentElement
返回当前元素的元素父节点children
只返回当前元素的元素子节点node.childElementCount === node.children.length
元素子节点个数firstElementChild
lastElementChild
返回最后一个元素节点nextElementSibling /previousElementSibling
兄弟元素节点
- 节点属性
nodeName
只读,节点名称nodeValue
节点值,可更改1nodeType
节点类型,只读attributes
属性节点集合
- 节点方法
Node.hasChildNodes()
是否有子节点
- 遍历节点树
-
增
document.createElement()
增加元素节点document.createTextNode()
增加文本节点document.createComment()
增加注释节点document.createDocumentFragment()
增加元素碎片节点
-
插
任何一个元素节点都有 appendChild 方法
.appendChild()
类似于剪切, 插入节点内容PARENTNODE.insertBefore(a,b)
增加元素节点 2, 在 b 前插入 a
-
删
-
替换
parent.replaceChild(new, origin)
新的替换老的元素
-
element
属性innerHTML
元素节点内添加内容- innerText(火狐不兼容)/ textContent(老版本 IE 不好使)
element
方法ele.setAttribute('class', 'demo')
- ele.className 可以直接改节点 class
ele.getAttribute()
3. 获取窗口属性,获取 dom
尺寸
- 滚动宽高
window.pageXOffset\ window.pageYOffset
(ie9 及以上)- (IE8 及以下)5
document.body.scrollLeft\scrollTop
document.documentElement.scrollLeft\scrollTop
6
// 获取屏幕滚动的距离 function getScrollOffest() { if (window.pageXOffset) { return { x: window.pageXOffset, y: window.pageYOffset } } else { return { x: document.body.offsetWidth + document.documentElement.offsetWidth, y: document.body.offsetHeight + document.documentElement.offsetHeight, } } }
- 获取可视宽高
window.innerWidth\innerHeight
- (IE8 及以下)
document.body.clientWidth\clientHeight
// 怪异模式 7
document.documentElement.clientWidth\clientHeight
// 标准模式
function getViewportOffset() { if (window.innerWidth) { return { width: window.innerWidth, height: window.innerHeight } } else { if (document.compatMode === 'BackCompat') { return { width: document.body.clientWidth, height: document.body.clientHeight } } else { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } } }
- 查看元素的几何尺寸
dom.getBoundingClientRect()
- 返回一个对象,对象中有
left
,top
,right
,bottom
等属性;left
,top
表示左上角的 x 坐标和 y 坐标,right
,bottom
表示右下角的 x 坐标和 y 坐标; height
和width
属性老版本 IE 并未实现- 返回的结果并不是实时的
- 返回一个对象,对象中有
-
- 查看元素尺寸
dom.offestWidth\offestHeight
- 查看元素位置
dom.offestLeft\offestTop
// 无定位父级,返回相对文档的坐标;有定位父级,返回相对于有定位父级的坐标
dom.offestParent
// 返回最近的有定位的父级
- 查看元素尺寸
- 滚动条滚动
window.scroll(x,y)\scrollTo(x,y)
// 滚动到指定位置
window.scrollBy(x,y)
// 滚动累加
4. 脚本 css
dom.style[prop]
可获取,可修改,获取内联样式window.getComputedStyle(div, null)
获取可视样式 只能获取 (IE8 及以下不适用) null 获取伪元素
二、事件
1. 事件绑定
-
dom.onclick = function(){};
this 指向自己dom.onclick = null;
// 取消事件
-
dom.addEventListener('click', function(){}, false)
this 指向自己 (IE9 及以上)dom.removeEventListener('click', function(){}, false)
取消事件
// 绑定事件
function addEvent(elem, e, func, i) {
var i = i || false;
if (elem.addEventListener) {
return elem.addEventListener(e, func, i)
} else {
return elem.attachEvent(e, func)
}
}
// 取消事件
function removeEvent(elem, e, func, i) {
var i = i || false;
if (elem.addEventListener) {
return elem.removeEventListener(e, func, i)
} else {
return elem.detachEvent(e, func)
}
}
-
dom.attachEvent('onclick', fun())
this 指向 window (IE 独有)dom.detachEvent('onclick', fun())
2. 事件处理模型
- 事件冒泡 (自底至上)
- 事件捕获 (自顶向下) IE 没有
dom.addEventListener('click', function(){}, true)
true 开启捕获 - 执行顺序,先捕获,后冒泡
- focus, blur, change, submit, reset, select 等事件不冒泡
3. 取消冒泡和阻止默认事件
- 取消冒泡
e.stopPropagation()
IE9 以下版本不支持e.cancelBubble = true
IE 独有 google 也有
function stopBubble(e) { var e = e || window.event; if (e.stopPropagation) { return e.stopPropagation } else { return e.cancelBubble = true } }
- 阻止默认事件
return false;
以对象的属性注册的事件才生效e.preventDefault();
W3C ie9 一下不兼容e.returnValue = false;
兼容 IE
- 事件对象
event || window.event(IE)
- 事件源对象
event.target
火狐只有这个
event.srcElement
IE 只有这个
chrome 都有
- 事件委托
利用事件冒泡和事件源对象进行处理
// 事件源
var ul = document.getElementByTagName('ul')[0];
ul.onclick = function(e){
var event = e || window.event,
target = event.target || event.srcElement;
console.log(target.innerText)
}
4. 事件方法
-
鼠标事件
- oncontextmenu 鼠标右击事件
- onmousemove onmouseup
e.button === 2 鼠标右键
e.button === 1 鼠标左键
-
键盘事件8
- keydown 当用户按下键盘上的任意键时触发,如果按住不放的话,会重复触发此事件;
- keypress 当用户按下键盘上的字符键时触发,如果按住不放的话,会重复触发此事件;
- keyup 松开按键
keydown 和 keypress 区别:
- keydown 内没有 charCode; keypress 有 charCode,返回 ASCII 码,转换成相应的字符
String.fromCharCode() // 根据 ASCII 码转换成字符
-
文本类事件
…etc
5. json,异步加载,时间线
json
JSON.stringify(); JSON.parse()
{
"name":'aa'
}
6. 异步加载
async
- 用于异步下载脚本文件。
- 当脚本文件下载完成后,会立即执行该脚本,而不会等待整个文档解析完成
- 如果有多个带有async属性的脚本,它们可能会按照它们到达的顺序开始下载,但执行顺序是不确定的。
- async属性只适用于外部脚本(即src属性指定的脚本)
defer
- defer 属性用于开启新的线程下载脚本文件,但脚本的执行会延迟到整个文档解析完成后进行。
- 与async不同的是,多个带有defer属性的脚本会按照它们在HTML文档中出现的顺序依次执行。
- defer属性也只适用于外部脚本。
<script src="script.js" defer></script>
- 示例:
// 异步加载
function loadScript(url, prop) {
var script = document.createElement('script');
script.type = 'text/javascript';
if (script.onload) {
script.onload = function () {
tools[prop]
}
} else { // IE
script.onreadystatechange = function () {
if (script.readyState === '' || script.readyState === 'loaded') {
tools[prop]
}
}
}
script.src = url;
document.head.appendChild(script);
}
三、 时间线
-
js 时间线
-
创建 Document 对象,开始解析 web 页面;
document.readyState = 'loading'
; -
link 遇到 css,创建线程加载,继续解析文档
-
script 外部 js,无设置 async、defer, 浏览器加载,并阻塞,解析完脚本,继续解析文档
-
script 外部 js,设置 async、defer, 浏览器创建加载,继续解析文档
async,脚本加载完立即执行;defer,解析完文档执行
异步禁止使用 document.write() -
img 正常解析 dom 结构, 异步加载 src,并继续解析文档
-
文档解析完,
document.readyState = 'interactive'
-
文档解析完,所有设置
defer
的脚本会按照顺序执行 -
document 对象触发
DOMContentLoaded
事件,标志解析完后,可以监听事件 -
当所有
async
脚本加载并执行后,img 等加载完后,document.readyState = 'loaded'
-
从此,以异步响应方式处理用户输入、网络事件等
-
-
window.onload
dom 解析并加载完readyState 参数:
-
DOMContentLoaded
文档解析完
document.addEventListener('DOMContentLoaded', function(){
})
BOM (Browser Object Model)浏览器对象
一、location 对象: location是window对象的一个属性, 包含有关当前 URL 的信息
location.search()
// 获取url参数,getlocation.assign()
// 跳转 记录浏览历史,可实现后退location.replace()
//跳转 不记录浏览历史,不可实现后退location.reload(true)
//重新加载, true 强制刷新