DOM
全名 Document Object Model
DOM可以想象成一棵树。
每一个分支就叫节点
Node
,Node
分为Docement
(html
),Element
(元素)和Text
(文本)以及其他不重要的。节点内容储存在内存里,每种节点存哪些属性是由
DOM
标准规定的。DOM
的功能就是将 页面中的节点通过构造函数构造成对象。构造函数关系.jpg
Q:DOM API需要背嘛?
A:不需要背,需要掌握它的增删改查作用!
Node接口
需要注意的几个点:
-
childNodes
和children
的区别。前者获取所有子节点,包括回车构成的text,后者获取的是子标签 -
first/lastChild
和first/lastElementChild
的区别。前者会获得回车构成的文本,后者是直接获得标签。造成这种区别的原因就是:DOM
一开始是给XML
用的。 -
nodeName
两个需要记住的:1document.documentElement.nodeName
返回的是"HTML"
2svg
标签 返回的是小写的"svg"
其他的全部返回的大写 -
textContent
和innerText
的区别。 前者获取包括script
和style
里面的内容,后者没有 -
nodeType
返回值 。1代表元素 3代表文本 -
nextSibling
会获取到回车构成的文本 - 方法
cloneNode()
分浅拷贝和深拷贝。浅拷贝只拷贝标签本身,深拷贝需要在括号里加上true
,会把标签和标签下的所有内容递归拷贝。 - 方法
isEqualNode
和isSameNode
的区别。 前者是长的一模一样,但不是同一个,后者就是同一个。
-添加文本内容的两个不同方法以及区别。1div.innerText = '2'
这种方法会清除原来的内容和标签,然后再加上'2' ; 2div.appenChild(document.createTextNode('2'))
这种方法会在原先内容并列的添加'2'。
- 属性
- childNodes 返回包含指定节点的子节点的集合,为动态集合
- firstChild 返回树中节点的第一个子节点,包含text
- innerText
- lastChild
- nextSibling 返回其父节点的
childNodes
列表中紧跟其后的节点,包含text - nodeName
- nodeType 表示的是该节点的类型
- nodeValue 属性返回或设置当前节点的值
- outerText
- ownerDocument
- parentElement
- parentNode
- previousSibling
- textContent 注意和innerText的区别
- 方法(如果一个属性是函数,那么这个属性就也叫做方法;换言之,方法是函数属性)
- appendChild()
- cloneNode() 注意深拷贝和浅拷贝
- contains()
- hasChildNodes()
- insertBefore()
- isEqualNode() 注意两者的区别
- isSameNode() 注意两者的区别
- removeChild()
- replaceChild()
- normalize() 将当前节点和它的后代节点”规范化“(normalized)。在一个"规范化"后的DOM树中,不存在一个空的文本节点,或者两个相邻的文本节点。
注一:“空的文本节点”并不包括空白字符(空格,换行等)构成的文本节点。
注二:两个以上相邻文本节点的产生原因包括:
- 通过脚本调用有关的DOM接口进行了文本节点的插入和分割等。
- HTML中超长的文本节点会被浏览器自动分割为多个相邻文本节点。
举例
var wrapper = document.createElement("div");
wrapper.appendChild(document.createTextNode("Part 1 "));
wrapper.appendChild(document.createTextNode("Part 2 "));
// 这时(规范化之前),wrapper.childNodes.length === 2
// wrapper.childNodes[0].textContent === "Part 1 "
// wrapper.childNodes[1].textContent === "Part 2 "
wrapper.normalize();
// 现在(规范化之后), wrapper.childNodes.length === 1
// wrapper.childNodes[0].textContent === "Part 1 Part 2"
Document接口
注意的点
-
document.write()
每次写入分三步 open>write>close,重新写入需要重新open,因此会造成一个重新写入会覆盖之前内容的结果。所以write
使用时不要出现延时或者异步。 - 关于
createDocumentFragment()
这是一个非常节省性能的操作,他和Document
最大的区别在于他不是真实DOM树的一部分,它的变化不会引起DOM树的重新渲染的操作reflow
,且不会导致性能等问题。
最常用的方法是使用文档片段(DocumentFragment)作为参数(例如,任何Node
接口类似Node.appendChild
和Node.insertBefore
,这种情况下被添加(append)或被插入(inserted)的是片段的所有子节点, 而非片段本身。因为所有的节点会被一次插入到文档中,而这个操作仅发生一个重渲染的操作,而不是每个节点分别被插入到文档中,因为后者会发生多次重渲染的操作。
面试题:请把<body><p>第1行</p><p>第2行</p>...</body>
(body之间有100个p元素)插入body
里面,注意:需要考虑到性能问题。
var oFrag=document.createDocumentFragment();
for(var i=0;i<100;i++)
{
var op=document.createElement("P");
var oText=document.createTextNode(i);
op.appendChild(oText);
oFrag.appendChild(op);
}
document.body.appendChild(oFrag);
- 属性
- body
- characterSet
- childElementCount
- children
- doctype
- documentElement
- domain
- fullscreen
- head
- hidden
- images
- links 返回一个包含文档中所有具有 href 属性值的
<area>
元素<a>
元素的集合。 - location
- onxxxxxxxxx
- origin
- plugins
- readyState
- referrer
- scripts
- scrollingElement
- styleSheets
- title
- visibilityState
- 方法
- close()
- createDocumentFragment()
- createElement()
- createTextNode()
- execCommand()
- exitFullscreen()
- getElementById()
- getElementsByClassName()
- getElementsByName()
- getElementsByTagName()
- getSelection()
- hasFocus()
- open()
- querySelector()
- querySelectorAll()
- registerElement()
- write()
- writeln() 向文档中写入一串文本,并紧跟着一个换行符。
作业题难点
-
元素 Element 的 NodeType 值为AC
A :1
B: '1'
C:Node. ELEMENT_NODE -
<div id=parent></div>
parent 的值为 C
A:就是这个 id 为 parent 的 div 对应的 Element 对象
B:父窗口
C:如果有父窗口,就是父窗口。如果没有,就是当前窗口 -
HTMLCollection与NodeList的区别有A C
A:HTMLCollection实例对象的成员只能是Element节点,NodeList实例对象的成员可以包含其他节点。
B: HTMLCollection实例对象都是动态集合,节点的变化会实时反映在集合中。NodeList实例对象都是静态集合。
C:HTMLCollection实例对象可以用id属性或name属性引用节点元素,NodeList只能使用数字索引引用。 -
var parent = document.getElementById('parent');
parent.childNodes.length // 2
parent.appendChild(document.createElement('div'));
parent.childNodes.length // 请问现在 length 是多少 3 -
var allDiv = document.querySelectorAll('div')
allDiv.length // 假设是 2
document.body.appendChild( document.createElement('div') )
allDiv.length // 请问现在 length 的值是多少???2
6.上面两题,为什么一个 length 会动态变化,另一个 length 却不会动态变化?A B
A:parent.childNodes 是动态集合。所谓动态集合就是一个活的集合,DOM树删除或新增一个相关节点,都会立刻反映在NodeList接口之中。
B:document.querySelectorAll方法返回的是一个静态集合。DOM内部的变化,并不会实时反映在该方法的返回结果之中。
网友评论