《DOM 启蒙》读书笔记及测试代码
- 节点概览
- 节点组成的树形层次结构
- 节点类型
3.节点继承 - 继承而来节点打交道的属性和方法
- 节点类型名称和值
Node.prototype.nodeTypeNode.prototype.nodeNameNode.prototype.nodeValue
- 创建节点
document.createElementdocument.createTextNodedocument.createCommentdocument.createAttributedocument.createDocumentFragment
- 字符串和节点的转换
Element.prototype.innerHTMLElement.prototype.outerHTMLNode.prototype.textContentElement.prototype.insertAdjacentElementElement.prototype.insertAdjacentTextElement.prototype.insertAdjacentHTMLHTMLElement.prototype.innerTextHTMLElement.prototype.outerText
- 插入节点
Node.prototype.insertBeforeNode.prototype.appendChildElement.prototype.beforeElement.prototype.afterElement.prototype.appendElement.prototype.prepend
- 移除替换节点
Node.prototype.removeChildNode.prototype.replaceChildElement.prototype.removeElement.prototype.replace
- 克隆节点
Node.prototype.cloneNode
- NodeList&HTMLCollection
length属性,因此可以是类数组对象- 实时反映
- 默认情况下,顺序与树中的顺序一致
- 遍历
- 节点(包括了注释、文本节点)
Node.prototype.parentNodeNode.prototype.firstNodeNode.prototype.lastNodeNode.prototype.nextSiblingNode.prototype.perviosSibling
- 元素(IE 9 才支持,因此 jQuery 利用上面的节点遍历相关属性模拟了下面的属性)
Element.prototype.fristElementChildElement.prototype.lastElementChildElement.prototype.nextElementChildElement.prototype.perviosElementChildElement.prototype.childrenElement.prototype.parentElementElement.prototype.previousElementSiblingElement.prototype.nextElementSibling
Element.prototype.childElementCount
- 节点(包括了注释、文本节点)
- 验证节点位置
Node.prototype.containsNode.prototype.compareDocumentPosition
- 比较节点
Node.prototype.isEqualNodeNode.prototype.isSameNode
- 文档节点
Object<-Node<-Document<-HTMLDocument- 属性和方法
- 通用信息
titleURLcharsetcontentTypecompatModeBackCompat(怪异模式)CSS1Compat(严格模式)referrerlastModified- 等等
- 快捷访问
doctype:现代浏览器不在document.childNodes中headbodydocumentElement:即<html lang="en">
- 探测特性
implementation.hasFeature
- 获取激活节点
- 是否聚焦在当前文档窗口上
- 获取全局对象
- 获取
document - 元素节点
HTML*Element- 创建元素,上面的
document.createElement - 标签名
Node.prototype.nodeNameElement.prototype.tagName
- 属性集合
- 操作属性
Element.prototype.getAttributeElement.prototype.setAttributeElement.prototype.hasAttributeElement.prototype.removeAttributeElement.prototype.getAttributeNSElement.prototype.setAttributeNSElement.prototype.hasAttributeNSElement.prototype.removeAttributeNSElement.prototype.getAttributeNodeElement.prototype.getAttributeNodeNSElement.prototype.setAttributeNodeElement.prototype.setAttributeNodeNSElement.prototype.removeAttributeNode
- 类操作
Element.prototype.classNameElement.prototype.classListaddremovetogglecontains
data-*属性HTMLElement.prototype.dataset
- 选取元素节点
- 特定元素
Element.prototype.querySelector和document.querySelectordocument.getElementById
- 节点列表
Element.prototype.querySelectorAll和document.querySelectorAll非实时的,下面三个是实时的。目前遇到的第一个非实时的获取方法。Element.prototype.getElementsByTagName和document.getElementsByTagNameElement.prototype.getElementsByTagNameNS和document.getElementsByTagNameNSElement.prototype.getElementsByClassName和document.getElementsByClassNamedocument.getElementsByName
- 子元素
Element.prototype.children实时、有序
- 预定义的节点列表
document.imagesdocument.embedsdocument.pluginsdocument.linksdocument.formsdocument.scriptsdocument.anchorsdocument.appletsdocument.childrendocument.styleSheets
- 验证选取的元素
Element.prototype.matchesSelector针对不同浏览器加前缀Element.prototype.webkitMatchesSelectorElement.prototype.mozMatchesSelectorElement.prototype.msMatchesSelectorElement.prototype.oMatchesSelectorElement.prototype.matches新的这个,不用加前缀
- 元素节点几何量与滚动几何量
- CSSOM 视图模块规范中定义了访问和操作元素节点可视化表象的元素几何量、滚动几何量的属性和方法。
- 相对
HTMLElement.prototype.offsetParent的位置 HTMLElement.prototype.offsetLeft相对于自身offsetParentHTMLElement.prototype.offsetTop相对于offsetParentElement.prototype.clientTop相对于自身边框Element.prototype.clientLeft相对于自身边框Element.prototype.scrollTop滚动元素Element.prototype.scrollLeft滚动元素- 相对视区的偏移
Element.prototype.getBoundingClientRectElement.prototype.getClientRects- 元素在视图中的尺寸
HTMLElement.prototype.offsetHeight包括边框HTMLElement.prototype.offsetWidth包括边框Element.prototype.getBoundingClientRect().width包括边框Element.prototype.getBoundingClientRect().height包括边框Element.prototype.clientWidth不包括边框Element.prototype.clientHeight不包括边框Element.prototype.scrollWidth滚动元素Element.prototype.scrollHeight滚动元素- 彻底弄清楚几个宽高
- 特定点上最顶层元素
document.elementFromPoint- 滚动元素到视区
Element.prototype.scrollIntoViewElement.prototype.scrollIntoViewIfNeeded
- 元素节点内联样式
- 获取内联样式
HTMLElement.prototype.style得到CSSStyleDeclaration
- 设置内联样式
- 直接通过
style获得、设置、删除内联样式属性 style.setPropertystyle.getPropertyValuestyle.removeProperty
- 直接通过
- 所有内联样式
style.cssTextElement.prototype.setAttribute、Element.prototype.getAttribute、Element.prototype.removeAttribute
- 计算样式
window.getComputedStyle上面获得样式都是内联,不叠加计算的,这个方法返回的是叠加计算后的实际值。window.getComputedStyle得到的CSSStyleDeclaration是只读的。
- 文本节点
Object<-Node<-CharacterData<-Text和元素混在一区的文本会转换为文本节点- 文本节点属性和方法
- 创建节点
- 字符(包括空白符和回车符)会创建文本节点
- 编程式创建:
document.createTextNode
- 节点值
Node.prototype.nodeValueNode.prototype.textContent会合并所有子文本节点CharacterData.prototype.dataText.wholeText
- 操作文本节点
CharacterData.prototype.appendDataCharacterData.prototype.deleteDataCharacterData.prototype.insertDataCharacterData.prototype.replaceDataCharacterData.prototype.substringDataComment也继承了CharacterData,所以也拥有这些方法
- 多个兄弟文本节点
- 拿上面的例子来说,
strong元素把文本截断,所以得到的childNodes的length为 3。 - 另外也可以编程式地添加两个文本节点,而不会合并。
Node.prototype.normalize合并兄弟文本节点。Text.prototype.splitText分割文本节点
- 拿上面的例子来说,
Node.prototype.textContent- 合并返回所有子文本的内容
- 设置的时候会移除所有子节点,替换为新的
Text节点 HTMLElement.prototype.innerText区别:innerText认识 Css,忽略隐藏文本。innerText关心 Css 触发重排。innerText使文本规范化。innerText非标准,新的火狐好像也支持了。
DocumentFragment节点(文档片段)- 空的文档模板,行为与实时 DOM 树相似,但是仅在内存中存在。
- 创建文档片段节点
document.createDocumentFragment- 与直接创建 div,然后创建 DOM 结构的区别:
- 文档片段可以包含任意节点(body、html 除外)。
- 文档片段插入 DOM 中时,自身不会添加,只插入子节点。
- 文档片段插入 DOM 中时实际上是把传输的内容放到了 DOM,自身的内容就没了。
- 在内存中创建节点注入到实时节点结构是极其高效的。
- 文档片段没有
innerHTML属性,变通方法是新建一个 div,利用 div 的innerHTML。 - 通过
Node.prototype.cloneNode将文档片段保存在内存中。 - Css 样式表和 Css 规则
- 样式概述
- 元素内联样式
HTMLLinkElement外部样式类HTMLStyleElement页面内联样式类CSSStyleSheet样式表对象类CSSStyleRule样式规则类
- 创建样式
document.createElement('style')document.createElement('link')
- 获取所有样式表
document.styleSheets(包括外部和内部)- 实时、
length属性、类数组对象。 - 单个样式表用
sheet属性从HTMLLinkElement或HTMLStyleElement获取
CSSStyleSheet的属性和方法CSSStyleRule的属性和方法- 修改样式规则
CSSStyleSheet的insertRule、deleteRule、addRule、removeRule方法。- 直接通过
CSSStyleRule.prototype.style进行修改。
CSSStyleSheet.prototype.disabled使样式表失效。- DOM 中的 JavaScript
- 脚本概述
- 元素内联脚本,
<a href="javascript:void(0)"></a>和<button onclick="alert('yo')"></button>等。 HTMLScriptElement页面内联脚本。HTMLScriptElement外部脚本。- 脚本元素内会新建一个文本节点,可以通过
innerHTML、textContent、innerText来获取值。
- 元素内联脚本,
- 同步加载和解析
- 如果加载和解析是异步的,那么
document.write输出的位置根本无法确定,而如果在onload事件之后调用document.write会自动触发document.open清空页面,因此 Js 默认采用了同步地加载方式,它会阻塞页面的解析。现代浏览器是支持并发下载脚本的。 - 页面内联脚本也是如此,会同步执行,阻塞页面解析。
- 因此在同步加载的情况下,把 Js 脚本放到页面底部是比较好的策略。
- 如果加载和解析是异步的,那么
- 异步加载脚本
- 首先异步加载的脚本中出现,
document.write会报错。 defer异步加载、在DOMContentLoaded事件之前有序执行。低版本的 IE 支持。async异步加载,加载完就执行,不利于依赖管理。IE 10 才支持,优先级高于defer。- 手动创建
script标签实现异步加载(前端模块加载器如:seajs、requirejs 使用的都是这种方式)。
- 首先异步加载的脚本中出现,
onload和onreadystatechange- 通常我们会为手动创建的
script标签绑定一个加载完成的回调,在之后做一些操作,比如 seajs 会在加载完以后把script元素及其事件删除,防止内存泄漏,因为 seajs 已经把脚本的内容保存在模块对象上,供延迟调用了。 - 而对于 IE 8 及以下的浏览器,
Node不支持onload事件,所以使用onreadystatechange来代替。
- 通常我们会为手动创建的
- 获取当前执行的脚本
document.currentScript- IE 6-9 下没有这个属性,兼容 IE 的方案。
- 获取所有脚本
document.scripts
- DOM 事件
- 三种添加事件监听方式
- 行内属性事件:
<div onclick="alert('click')"></div> - 属性事件:
mdiv.onclick = () => alert('click') addEventListener:mdiv.addEventListener('click',() => alert('click'), false)(回调函数的this自动绑定到该元素,并且支持绑定多个回调)- IE
attachEvent不支持捕获阶段。
- 行内属性事件:
- 事件类型
UIEventload、onload、abort、error资源加载相关resize、scroll窗口尺寸相关context menu右键菜单
FocusEventblur、focus、focusin、focusout
FormEventchange、reset、submit、select
MouseEventclick、dbclickmousedown、mouseupmouseenter、mouseout不冒泡mouseleave、mouseover冒泡mousemove
WheelEvent- 浏览器里用的是
mousewheel规范用的是wheel
- 浏览器里用的是
KeyboardEventkeydown、keyup、keypress
TouchEventtouchstart、touchendtouchmove、touchcanceltouchenter、touchleave
- 拖拽相关
drag、dragover、dropdragstart、dragenddragenter、dragleave
- 文档相关
readystatechangeDOMContentLoaded
- 其它
afterprint、beforeprintbeforeuploadhashchangemessageoffline、onlinepagehide、pageshow
- 移除事件监听
removeEventListener只支持通过函数引用添加的事件监听函数。- IE
detachEvent。
- 事件捕获和冒泡
addEventListener第三个参数为true则在捕获阶段触发、false则在冒泡阶段触发,默认是false。- 其他两种事件绑定都是在冒泡时触发的。
- IE
attachEvent不支持捕获阶段,也没有第三个参数,都是在冒泡阶段触发。
- 常见事件对象属性
target和currentTarget,currentTarget是当前活动对象,target是目标对象,只有在目标阶段,两者才是相等的。- 五个坐标,见彻底弄清楚几个宽高 。
stopPropagation:因为事件可以在各层级的节点中传递, 不管是冒泡还是捕获, 有时我们希望事件在特定节点执行完之后不再传递, 可以使用事件对象的stopPropagation方法。preventDefault:元素上带有的功能. 如: 点击 a 链接节点的跳转动作, 点击 submit 按钮表单会提交等,如果监听这些元素的事件时不希望执行默认动作,就可以使用preventDefault方法。return false:退出执行, return false 之后的所有触发事件和动作都不会被执行。有时候return false可以用来替代stopPropagation和preventDefault,除此之外,还可以返回对象, 跳出循环等。stopImmediatePropagation:和stopPropagation区别是这个方法会把绑定在同一个元素的剩下的回调都取消。eventPhase属性,0 表示不在事件中,1 表示捕捉阶段、2 表示目标阶段、3 表示冒泡阶段。- 需要注意的是
event是实时的,也就是说在console输出的event已经不是当时的那个event了。
- 自定义事件
document.createEventinitCustomEvent(event,bubble?,cancelable?,event.detail)fireEvent(IE) 和dispatchEvent- IE9 里
initCustomEvent需要第四个参数。 - DOM4 里面添加了
CustomEvent。
- 模拟出发鼠标事件
- 类似
jQuery.trigger()方法。 - 借助
initMouseEvent来实现。
- 类似
- 事件委托
- 事件委托是借助事件冒泡机制,用父级元素来统一管理子级的相同事件。
- 原理是不管是哪个子级触发的相同事件,都可以通过
event.target拿到这个子级元素,然后对其做相应的操作,因为操作逻辑是一样的,因此可以在父级中复用逻辑。 - 在处理
click、mousedown、mouseup、keydown、keyup、keypress等事件时十分有效。 - 可以有效的减少绑定,降低内存消耗。
本文深入讲解DOM树结构、节点操作、事件处理等核心概念,覆盖创建、选择、修改、删除节点的方法,以及如何通过JavaScript控制DOM元素的样式和布局。
1599

被折叠的 条评论
为什么被折叠?



