DOM基础知识

DOM相关api
textContent与innerText与innerHTML的区别
nodeType的值对应什么节点
documentFragment性能优化

DOM

Document Object Model,文档对象模型
即:把html当做对象来操作

Node节点(元素)相关api

获取

  • 元素.childNodes 获取该元素的所有子节点,包括换行形成的text节点。返回一个伪数组
  • 元素.childNodes[0]
  • 元素.children 获取该元素的所有子标签,不包括换行。返回一个伪数组
  • 元素.children[0]
  • 元素.parentNode 与 元素.parentElement
  • 元素.firstChild 与 元素.firstElementChild
  • 元素.lastChild 与 元素.lastElementChild
  • 元素.previousSibling 与 元素.previousElementSibling
  • 元素.nextSibling 与 元素.nextElementSibling
  • 元素.parentNode 与 元素.parentElement
  • 元素.nodeName 与 元素.tagName 返回的是大写的字符串,比如’DIV’,在做if判断时要配合toLowerCase使用
  • 元素.innerHTML 与 元素.innerTEXT 与 元素.textContent
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <footer id="footer">
    <p>hello
    <script>document.write('2014-' + new Date().getFullYear())</script>
    world
    </p>
    </footer>
    footer.textContent 与 footer.innerText返回结果一样:
    'hello
    document.write('2014-' + new Date().getFullYear())
    world'
    1.textContent会将style标签里的内容当做文本返回,而innerText会忽略style标签里包含的内容
    2.innerText不会返回display:none的元素的文本,而textContent会
    --------------------------------
    footer.innerHTML的返回结果:
    ' <p>hello
    <script>document.write('2014-' + new Date().getFullYear())</script>2014-2018
    world
    </p>'

面试题textContent与innerText的区别

1
2
3
4
5
6
<div id="test" class="test">test<div style="display:none"><span>test</span></div><style>hi</style></div>
<script type="text/javascript">
var testDiv = document.getElementById('test');
console.log(testDiv.textContent);
console.log(testDiv.innerText);
</script>
  • textContent会获取所有元素的内容,包括 <script><style> 里包含的内容。而innerText不会
  • textContent会获取display:none的节点的文本;而innerText不会返回隐藏元素的文本
  • 由于 innerText 受 CSS 样式的影响,它会触发回流(reflow),但textContent 不会。

innerHTML

获取时,会将包含的标签还原出来

1
2
3
<div id='x'><p>hello</p></div>
x.innerHTML // <p>hello</p>

设置时,会将标签转成代码

1
x.innerHTML='<i>hello</i>' // i标签自动转成斜体

面试题nodeType

  • nodeType=1 元素节点(标签),例如

    ,

  • nodeType=2 属性节点 比如class=”right”
  • nodeType=3 文本节点 例如p标签里包含的文字
  • nodeType=8 注释节点
  • nodeType=9 document文档节点
  • nodeType=10 文档类型节点 比如html的文档类型是<!DOCTYPE html>
  • nodeType=11 documentFragment文档片段节点
    1
    2
    3
    4
    5
    document.nodeType === Node.DOCUMENT_NODE
    // true
    document.nodeType === 9
    // true

面试题documentFragment性能优化

查看相关博客

操作DOM

  • ul.appendChild(li) 把li插入ul的末尾内
  • div1.cloneNode(deep?)
    浅拷贝

深拷贝

  • 元素.hasChildNodes() 元素是否含有子节点,有的话返回true,换行算作文本节点
  • ul.insertBefore(li, ul.children[0]) 把新节点插到ul最前面内
  • div1.isEqualNode(div2) 检查两个元素是否相等
  • div1.isSameNode(div2) 检查两个元素所有有相同节点。推荐使用div1===div2来代替此方法
  • ul.removeChild(ul.lastElementChildren)
  • ul.replaceChild(newLi, oldLi)
  • 元素.normalize() // 常规化

document相关api

获取

  • document.body // <body>...</body>
  • document.children // 伪数组[html]
  • document.documentElement // <html>...</html>
  • document.domain // “xiedaimala.com”
  • document.origin // “https://xiedaimala.com
  • document.head // <head>...</head>
  • document.images //获取页面中所有的<img>标签。通过document.images.length可以获取<img>标签数量
  • document.links //获取页面中所有的<a>标签。通过document.links.length可以获取<a>标签数量
  • document.location
  • document.referrer //引荐人。从哪里跳转到这个页面的
  • document.title
  • document.onxxxxx //onclick,onmouseover…….

操作document

  • document.getElementById()
  • document.getElementsByClassName()
  • document.getElementsByTagName()
  • document.querySelector() //只获取满足条件的第一个元素
  • document.querySelectorAll() //返回一个伪数组
  • document.createDocumentFragment()
  • document.createElement()
  • document.createTextNode()
  • document.write() //紧接着写
  • document.writeln() //一行一行(line)写

Element相关api

https://developer.mozilla.org/zh-CN/docs/Web/API/Element

作业题

1
2
3
4
5
6
var parent = document.getElementById('parent');
parent.childNodes.length // 2
parent.appendChild(document.createElement('div'));
parent.childNodes.length // 请问现在 length 是多少
答案:3

1
2
3
4
5
6
7
8
9
10
var allDiv = document.querySelectorAll('div')
allDiv.length // 假设是 2
document.body.appendChild( document.createElement('div') )
allDiv.length // 请问现在 length 的值是多少???
答案:2
将最后一段代码改成
allDiv = document.querySelectorAll('div') //在使用querySelector方法时,遇到DOM树增加或删除,需要重新获取
allDiv.length // 3

上面两题,为什么一个 length 会动态变化,另一个 length 却不会动态变化?

1.parent.childNodes是动态集合。所谓动态集合就是一个活的集合,DOM树删除或新增一个相关节点,都会立刻反映在NodeList接口之中。
2.document.querySelectorAll方法返回的是一个静态集合。DOM的增删,并不会实时反映在该方法的返回结果之中。

-------------本文结束感谢您的阅读-------------