DOM

文章目录

节点层次

  1. 文档只有一个根节点,即document,html为其唯一的子节点

节点类型

一共具有12中节点类型,所有节点都继承自Node类型

  1. Node.ELEMENT_NODE(1)
  2. Node.ATTRIBUTE_NODE(2)
  3. Node.TEXT_NODE(3)
  4. Node.CDATA_SECTION_NODE(4)
  5. Node.ENTITY_REFERENCE_NODE(5)
  6. Node.ENTITY_NODE(6)
  7. Node.PROCESSING_INSTRUCTION_NODE(7)
  8. Node.COMMENT_NODE(8)
  9. Node.DOCUMENT_NODE(9)
  10. Node.DOCUMENT_TYPE_NODE(10)
  11. Node.DOCUMENT_FRAGMENT_NODE(11)
  12. Node.NOTATION_NODE(12)

属性

  • nodeType 上方12中之一
  • nodeName
  • nodeValue

对于元素节点,nodeName中保存的都是元素的标签名,nodeValue保存的始终是null

节点关系

每一个节点都保存着一个childNodes属性,保存着一个NodeList对象,指向子节点

NodeList通过下面属性访问

  1. 方括号
  2. .item()

关系:

  • childNodes // NODE LIST
  • children // HTML COLLECTION
  • firstChild
  • lastChild
  • parentNode
  • previousSibling
  • nextSibling
  • element.compareDocumentPosition()
    • 1 无关
    • 2 居前
    • 4 居后
    • 8 包含
    • 16 被包含

操作节点

  • hasChildNodes()
  • appendChild() 如果传进去appendChild的节点已经是文档的一部分,则将该节点从原来的位置转移到新位置
  • insertBefore(newNode, node) 第二个参数为参照节点
  • replaceChild(newNode, node) 第二个参数为移除的节点
  • removeChild(node) 跟上面一样,移除的节点还是归文档所有,只是在文档中已经没有其位置了
  • cloneNode(bool) 创建一个副本,bool表示是否深度复制
  • normalize() 找到空文本节点删除,找到相邻文本节点合并

Document类型

document为window的一个属性,因此可以当成全局变量访问

  • nodeType === 9
  • nodeName === ‘#document’
  • ownerDocument === null
  • 子节点可能是一个DocumentType、Element、ProcessingInstruction 或者 Comment
  • document.documentElement为html元素
  • document.body保存body引用
  • document.head
  • document.doctype
  • document.compatMode
    • CSS1Compat
    • BackCompat
  • document.title
  • document.URL, document.domain, document.referrer 其中document.domain只能设置为URL中包含的域
  • document.readyState
    • loading
    • complete
  • document.charset & document.defaultCharset
  • document.importNode(node, bool) 可以传入ownerDocument不是当前文档的node,支持两个属性,一个为node,一个为是否深复制

nodeList 和 HTMLCollection 区别
HTMLCollection 只包含元素节点,NodeList包含任何类型的节点
HTMLCollection 多了一个 namedItem() 方法,接受一个 id 或者 name

查找元素

  • getElementById()

  • getElementsByTagName() 不区分大小写

  • getElementsByName() 元素也支持这个方法,搜索起点为当前元素

  • querySelector() & querySelectorAll() 可以再document和element中使用,返回一个NodeList对象,但是底层实现类似于一组元素快照,而不是不断对文档进行搜索的动态查询。// 此处的 NodeList 不会动态更新

  • getElementsByClassName()

  • matchesSelector() 返回一个布尔值

获得的对象为HTMLCollection

  • 方括号访问(数字或者字符串(name))
  • namedItem(name or id)
  • item(index)

特殊集合,都为HTMLCollection

  • document.anchors 带有name的a元素
  • document.forms 文档中所有form元素
  • document.images 文档中所有img元素
  • document.links 文档中所有带href特性的a元素
  • document.styleSheets 文档中的样式表,包含style标签定义的样式表

文档写入

  • document.write()
  • document.writeIn() ‘\n’
  • document.open()
  • document.close()

Element 类型

  • tagName === nodeName 标签名始终以大写表示
  • id、title、lang、dir、className
  • getAttribute()、setAttribute()、removeAttribute()
  • attributes –> namedNodeMap 拥有以下方法,保存着attr类型节点,可以通过specified查看是否定义了属性
    • getNamedItem(name)
    • removeNamedItem() 返回删除的attr节点,可以通过返回节点的nodeValue和nodeName来访问
    • setNamedItem()
    • item(pos)
  • classlist –> DOMTokenList
    • add()
    • contains()
    • remove()
    • toggle()
  • dataset 自定义属性
  • innerHTML html以及table等标签不支持innerHTML
  • outerHTML
  • innerText
  • outerText
  • insertAdjacentHTML()
    • “beforebegin”
    • “afterbegin”
    • “beforeend”
    • “afterend”
  • children
  • contains() 某一个节点是不是另一个节点的后代
  • document.createElement(name) 创建Element节点
  • .isSameNode() 判断对象是否相等
  • .isEqualNode() 判断是否同一引用

Text 类型

  • nodeType === 3
  • nodeName === ‘#text’
  • nodeValue 为文本
  • 不支持子节点
  • data 文本
  • textContent
  • appendData()
  • deleteData(offset, count)
  • insertData(offset, count)
  • replaceData(offset, count, text)
  • splitText(offset) 分成两个文本节点
  • substringData(offset, count)
  • document.createTextNode()

DocumentFragment 类型

  • document.createDocumentFragment()

操作表格

Table:

  • caption
  • tBodies
  • tFoot
  • tHead
  • rows HTMLCollection
  • createTHead
  • createTFoot
  • createCaption
  • deleteTHead
  • deleteTFoot
  • deleteCaption
  • deleteRow(pos)
  • insertRow(pos)

TBody:

  • rows
  • deleteRow(pos)
  • insertRow(pos)

Tr

  • cells
  • deleteCell(pos)
  • insertCell(pos)

NodeList

  • NodeList
  • NamedNodeMap
  • HTMLCollection
  • DOMTokenList

元素遍历

  • childElementCount
  • firstElementChild
  • lastElementChild
  • previousElementSibling
  • nextElementSibling

焦点管理

  • document.activeElement
  • document.hasFocus() 返回布尔值

scrollIntoView

  • scrollIntoView(bool) true/default:顶部尽可能平齐, false:底部尽可能平齐

DOM子集模块

  • DOM2 级核心Core
  • DOM2 级视图View
  • DOM2 级事件Events
  • DOM2 级样式Style
  • DOM2 级遍历和范围 Traversal and Range
  • DOM2 级HTML

样式

支持style特性的HTML元素在JavaScript中都会有一个对应的style属性

其中,具有横杠的属性自动转换成驼峰式,float => cssFloat // float为JavaScript中的一个保留字
在标准模式下,所有度量值都必须要指定一个单位,否则会被忽略

style对象 extends CSSStyleDeclaration:

  • cssText
  • length 应用给元素css属性的数量,缩写会自动展开
  • removeProperty()
  • item(index) 可以通过for循环遍历属性

计算的样式

document.defaultView.getComputedStyle(),接受两个参数,第一个参数为元素,第二个参数为伪元素(如”:after”或者”::after”)

操作样式表

document.styleSheets & styleOrLinkElement.sheet
CSSStyleSheet extends StylesSheet

  • disabled 可写,是否禁用样式表
  • href 样式表的href,style标签的为null
  • media 当前样式表支持的所有媒体类型的集合,如果是空列表,表示适合所有媒体类型的集合
  • cssRules 包含的规则
  • insertRule(rule:str, index)
  • deleteRule(index)

元素大小

  • offsetHeight // border-box
  • offsetWidth
  • offsetTop 与offset parent 之间的距离
  • offsetLeft
  • offsetParent
  • clientHeight padding-box

  • clientWidth

  • clientTop

  • clientLeft

  • scrollHeight 没有滚动条下元素总高度,即所有内容的高度 // padding-box

  • scrollWidth

  • scrollTop 设置此可以改变元素的滚动位置

  • scrollLeft

getBoundingClientRect() // border-box
返回相对于视口的 left right top bottom

特殊集合

HTMLCollection: 一般为以下方法获得:
动态改变

  • getElementsByTagName
  • getElementsByClassName
  • element.children
  • document.anchors 带有name的a元素
  • document.forms 文档中所有form元素
  • document.images 文档中所有img元素
  • document.links 文档中所有带href特性的a元素

NodeList:
不会动态改变

  • getElementsByName
  • querySelectorAll
  • element.childNodes

DOMTokenList:
动态改变

  • element.classList

NamedNodeMap:
动态改变

  • element.attributes

StyleSheetList

  • document.styleSheets 文档中的样式表,包含style标签定义的样式表

遍历

DOM的遍历是要给深度优先的算法

NodeIterator

1
2
3
4
5
6
7
8
9
10
11
12
const ni = document.createNodeIterator(root, whatToShow, filter)
// NodeFilter.FILTER_ACCEPT
// NodeFilter.FILTER_SKIP
// NodeFilter.SHOW_ELEMENT
// filter:
function filter(node) {
return node.nodeName.toLowerCase() === 'section' ? NodeFilter.ACCEPT : NodeFilter.SKIP
}

// usage
ni.nextNode()
ni.previousNode()

TreeWalker

用法与NodeIterator差不多,增加了下面的功能

  • parentNode
  • firstChild
  • lastChild
  • nextSibling
  • previousSibling

NodeFilter.SKIP 跳过某个节点 NodeFilter.REJECT 跳过一整个子树
可以通过修改currentNode 来修改遍历的起点

Range

1
const range = document.createRange()

方法:

  • selectNode()
  • selectNodeContent()

Event

事件是利用侦听器来预定一些文档或浏览器窗口发生的一些特定的交互瞬间,这个模型称为观察者模型

事件流

事件流描述的是从页面中接收事件的顺序。
IE的事件流是事件冒泡流,网景的是事件捕获流

DOM2规定的时间流包括三个阶段:事件捕获阶段、处于目标阶段以及事件冒泡阶段。

规范要求,捕获阶段不会涉及事件目标

处理程序

1
2
3
4
5
6
addEventListener(eventType, callback, caption? or option?)
option = {
capture: bool,
once: bool,
passive: bool, // never call preventDefault
}

event object

  • type
  • eventPhase:1.捕获阶段 2.处于目标 3.冒泡阶段
  • bubble:是否冒泡
  • defaultPrevented:是否已经阻止默认行为
  • currentTarget
  • target
  • preventDefault(),只有cancelable为true的事件才可以使用
  • stopPropagation()
  • trusted:浏览器生成的为true,开发者通过JavaScript创建的为false
  • stopImmediatePropagation() 取消事件的进一步捕获或者冒泡,同时阻止任何事件处理程序被调用

兼容性

event || window.event
event.target || window.event.srcElement
event.stopPropagation || window.event.cancelBubble = true
event.preventDefault || window.event.returnValue = false

事件类型

  • UI事件:load、unload、abort(用户停止下载)、error(JavaScript运行错误)、select、resize、scroll
  • 焦点事件:blur、focus、focusin、fucusout(后两个支持冒泡)
  • 鼠标事件:click、dbclick、mousedown、mouseenter、mouseleave、mousemove、mouseout、mouseover、mouseup
  • 滚轮事件:mousewheel(包含clientX、clientY、pageX、pageY、screenX、screenY等)
  • 文本事件
  • 键盘事件
  • 合成事件
  • 变动事件

根据DOM2规范,应该在document上触发onload事件而不是window上

mouseleave与mouseenter:首次移动到/离开元素范围触发,不冒泡!,移动到后代元素上不会触发
mouseout与mouseover:首次移动/离开元素范围触发,移动到后代元素上触发

mousewheel包含一个wheelDelta属性

分享到: