document object model: 是 html 和 xml 文档的编程接口,提供了对文档的 结构化表述
,定义了一种方式提供给程序对该结构进行访问,从而改变文档的结构、样式和内容。 这个结构是一个集合
,也称之为树,每个节点的值是一个对象,包含该节点的属性和方法。dom
将页面和程序语言连接起来。
// dom tree example
"people": {
"person": [{
"address": [{
"@street": "321 south st",
"@city": "denver",
"@state": "co",
"@country": "usa"
}, {
"@street": "123 main st",
"@city": "arlington",
"@state": "ma",
"@country": "usa"
}],
"@first-name": "eric",
"@middle-initial": "H",
"@last-name": "jung"
}
]
}
学习总结计划
目录
document
属性,指向的是 dom tree
html
例如
<a href="https://github.com/heyunjiang">heyunjiang</a>
元素节点:a
,属性节点:href
,文本节点:heyunjiang
#text
一:element api
attributes
: 节点属性集合,伪数组, NamedNodeMap
hasChildNodes
: 节点的后代节点集合,包含文本节点, NodeListcompareDocumentPosition()
: a.compareDocumentPosition(b),比较a,b两个节点的位置关系isContentEditable()
getAttributeNode()
, removeAttribute(), removeAttributeNode()
, setAttribute(), setAttributeNode()
hasAttributes()
: 前者判断是否有某个属性,后者判断是否有属性isEqualNode()
: a.isEqualNode(b),比较a,b两个节点是否相等isSameNode()
: a.isSameNode(b),判断2个节点是否是同一节点normalize()
: 移除节点内部空的文本节点,连接相邻的文本节点(主要用于合并相邻文本节点)ownerDocument
: 返回节点所属 dom treeitem()
: childNodes[0] === childNodes.item(0)textContent
: 返回节点及所有子节点的文本内容,包括 script 的内容getBoundingClientRect()
: 返回元素大小及其相对于视口的位置,返回 DOMRect
对象; 如果要相对于网页左上角的位置,可以加上 window.scrollTop 或 window.scrollLeft 的值getClientRects()
: 返回元素 getBoundingClientRect() 集合,数组每一项代表每一行的 getBoundingClientRect() 数据。当元素为行内元素,然后跨行展示(多为span+文本)的时候,可以返回每一行数据的 getBoundingClientRect() 数据;当元素为块级元素,集合数组只有一项insertAdjacentElement(position, element)
: 将目标元素插入到节点的相对位置, position 有4个值: beforebegin, afterend, afterbegin, beforeendinsertAdjacentHTML(position, text)
:类似 insertAdjacentElement ,只是它要求的是 element string 就行insertAdjacentText(position, element)
: 同 insertAdjacentElement ,但是它 ie 不支持matches(selectorString)
: 判断是否有对应子节点。selectorString 为 css 选择符。可以用 matchesSelector()
、 querySelectorAll()
替代判断, ie9+requestFullscreen()
: 发出异步请求,让元素进入全屏模式。需要加浏览器前缀使用: webkitRequestFullScreen
、 mozRequestFullScreen
、 msRequestFullscreen
scrollIntoView()
: 让当前元素滚动到浏览器窗口的可视区域内innerText
: 表示一个节点及其后代的渲染文本内容getRootNode()
: 获取根节点,ie 不支持 (可以使用 ownerDocument 属性,都支持)contains(el)
: 判断当前节点是否有 el 这个子节点,ie5+addEventListener(type, listener ,{capture: Boolean, passive: Boolean, once: Boolean})
: 绑定事件, capture 表示是否在事件捕获阶段就触发; once 只触发一次,随后自动移除 listener ; passive 表示是否忽略 preventDefault 事件。视口:浏览器视口,就是浏览器标签栏以下的那个物理窗口
二:document api
document.documentElement
, document.body, document.head 没有 document.htmldocument.referrer
(表示从哪儿来的), document.title, document.URLdocument.documentElement.contains(el)
: 判断 document 是否拥有 el 这个节点document.defaultView
问:为什么 html 的 namespaceURI
总是 http://www.w3.org/1999/xhtml
?
三:attributes api (属性节点 api)
element.getAttributeNode(); // 必须加参数
element.attributes,返回该节点的所有属性节点结合,伪数组;
伪数组方法
[0]
每一个属性节点有下列属性或方法
四:dom event api
HTMLElement,继承自 Element, Node, EventTarget 接口;通常用到的 div, p
等,继承自 HTMLElement
event 句柄(执行方式 element.onxxx)
onabort
: 图像的加载被中断onerror
: 图像或文档加载出错onload
: 图像或文档加载成功onanimationcancel
: 当动画意外中断时触发onanimationiteration
: 当动画运行到最后一帧时触发 草案中, chrome -> webkitonloadstart, onload, onloadend
:执行顺序依次是 ‘loadstart’ fires first, then ‘load’, then ‘loadend’onselect, onselectionchange, onselectstart
: 当文字被选中时触发的事件onresize
:通常绑定在 window 对象身上,表示窗口大小改变事件onsubmit, onreset
: 用于表单event 属性
event 方法
dispatchEvent()
触发,不支持ieEvent
对象,使用 dispatchEvent()
触发,不支持ie在
非ie
中,不再建议使用 createEvent() 与 initEvent() 创建自定义事件了;在ie
中,必须使用 createEvent() 与 initEvent() 创建自定义事件
鼠标属性
ALT
是否被按下CTRL
是否被按下meta
是否被按下SHIFT
是否被按下五:addEventListener 第三个参数详解
{capture, passive, once}
在旧版本的浏览器中,第三个参数为布尔值
事件触发阶段:捕获阶段、元素阶段、捕获阶段
在规范中,passive 默认为 false
;但是在某些浏览器的实现中,在 touchStart
和 touchMove
事件中,已经默认设置 passive 为 true
,所以无法调用 e.preventDefault
阻止浏览器主线程的滚动。
解决方法是,通过显示设置 passive 的值为 false 来覆盖这个行为
var passiveIfSupported = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
} catch(err) {}
window.addEventListener('scroll', function(event) {}, passiveIfSupported );
1
不在同一文档中2
b 在 a 之前4
b 在 a 之后8
b 包含 a16
a 包含 b32
待定问题:以下输出为什么是10, 10又代表什么
<div id="hello"><p id="world">fa</p></div>
console.log(document.getElementById('world').compareDocumentPosition(document.getElementById('hello')))
判断2个节点是否相等,需要满足下列条件
这5个dom属性,会把空格、回车(换行符)当做文本节点来处理
解决方式: 都增加 Element
,比如 firstChild -> firstElementChild, childNodes -> children
clientHeight: height + padding
offsetHeight: height + padding + border + margin + 水平滚动条高度
scrollHeight = scrollTop + clientHeight
element.getBoundingClientRect(): 返回一个对象,包含 left, top, right, bottom[, width, height, x,y],都是相对于视口左上角而言。这个方法主要用于做节点定位,相对于浏览器定位,类似于 fixed 定位那种,相对于浏览器操作的
element.getClientRects(): 类似 getBoundingClientRect() ,但是当元素节点为行内元素,并且内容产生了换行,它就会返回每一行的 getBoundingClientRect() 数据。这个主要用于批量获取 getBoundingClientRect() 数据
insertAdjacentHTML 的 position
取值
主要使用的有: appendChild()
removeChild()
replaceChild()
insertAdjacentHTML(position, element)
通常用于视频、音频的全屏播放
不总结太多,以后用到再学
scrollIntoView()
基础支持:参数为 boolean:true -> 元素的顶端和其所在滚动区的可视区域的顶端对齐(github), false -> 同 true 相反,底端对齐
高级支持:scrollIntoViewOptions,一个 object ,可以设置滚动的流畅度,高版本 chrome 支持
答:clientHeight: 只读属性,表示 css height
+ padding
,不包括 border,margin,水平滚动条高度,通常用于展示区域内容占用了多少空间。
offsetHeight: 只读属性,表示 height
+ padding
+ border
+ margin
+ 水平滚动条的高度
,通常用于展示节点占据的实际高度。offsetHeight 比 clientHeight 多了边框、外边距、水平滚动条高度。如果元素没有使用 scale
或类似的放大缩小属性,offsetHeight 与 getBoundingClientRect() 返回的高度一致,如果使用了放大或缩小属性,那么 offsetHeight 的值不变, getBoundingClientRect()
会返回实际渲染的高度,所以要操作浏览器物理定位,还是要使用 getBoundingClientRect()
scrollHeight: 只读属性,表示元素内容区域的实际大小,会返回可滚动内容的所有height + padding
property:为 dom 节点的 属性
,包括 attributes, className, scrollTop 等
attribute:为 dom 节点下面的 属性节点
,dom 属性 attributes 返回的就是该 dom 节点下所有属性节点的集合
<a href="https://heyunjiang.github.io" id="testId" class="hello world">heyunjiang</a>
const ele = document.getElementById('testId');
// property
ele.className; // "hello world"
ele.classList; // ["hello", "world"]
ele.href; // "https://heyunjiang.github.io"
// attribute 通过 节点属性 attributes
const attributes = ele.attributes;
attributes.getNamedItem('id'); // 返回节点对象 id="testId"
// attribute 通过 节点方法
ele.getAttribute('id'); // "testId"
ele.getAttributeNode('id'); // 返回节点对象 id="testId"
clientX: 相对于浏览器定位
screenX:相对于显示器定位
offsetX:相对于 target 定位
Node.textContent: 返回自身及后代所有元素的文本值,会获取 script 、 style 元素的内容, 会获取隐藏元素的文本,不会触发重绘,不会将文本解析为 html
Node.innerText: 返回自身及后代所有元素的 渲染 文本内容属性, 会触发重绘,不会将文本解析为 html
Node.innerHTML: 返回或插入 html 文本,会自动将文本解析为html
第四点总结:如果只是设置节点的文本属性,直接使用
textContent
,性能更好、更安全,因为省去了解析为html这一步;获取当前浏览器渲染的文本内容使用innerText
;获取 dom tree 的所有文本内容使用textContent
;插入或设置 html string 使用innerHTML
isEqualNode: 判断2个节点是否特征相等,包括属性节点相同、内容相同、子节点相同,可以用去节点相同去重
isSameNode: 判断2个节点是否是同一个节点
NodeList 接口提供了 forEach、entries、keys、values 方法,比如 querySelectorAll 实现的就是 NodeList 接口;
而 HTMLCollection 没有实现 forEach 等方法,比如 getElementsByTagName 实现的就是 HTMLCollection 接口
共同点:都提供了iterator接口,可以使用 for of 遍历
通常 querySelector() 系列,都是根据当前节点向下查找节点;
closest()是根据当前节点,向上查找节点,是最近的、满足选择条件的节点。
属于对常见 dom api 的一个补充,多来自 mdn
属性
HTMLCollection
dom4
,ie 不支持
高版本 chrome 支持
ie6 支持
方法
inserAfter
问题,ie 不支持
ie 不支持
chrome、firefox支持
ie 不支持
高版本 chrome 支持
ie 不支持
ie 不支持
ie 不支持
ie 不支持
属于 h5 新的 dom api,也叫页面可见性 api
兼容:ie11+、ios safari10.3+
总共3部分组成
1 document.hidden
布尔值,表示当前页面是否处于浏览器最小化、后台标签页、预渲染状态中(浏览器被其他软件遮盖不算,因为浏览器只能判断自身bom、dom变化)
2 document.visibilityState
四个值
3 document.onvisibilitychange
当浏览器可见性变化的时候,触发的事件
以下元素支持 accesskey 属性:a, area, button, input, label, legend, textarea
通常按下快捷键的时候,让元素获得焦点
chrome: alt
+ accessKey
返回元素的class集合,只读属性,伪数组, DOMTokenList
方法:
兼容: ie10+
伪数组:DOMTokenList, HTMLCollection, NamedNodeMap, NodeList