DOM

1.DOM是什么

  • DOM(文档对象模型)是针对HTML和XML文档的一个API。DOM可以将任何HTML和XML文档描绘成一个层次化的节点树。节点分为不同的类型。

例如这样一段HTML:

<html>

	<head>
	
		<title>文档标题</title>
	
	</head>
	
	<body>
	
		<a href=“”>我的链接</a>
		
		<h1>我的标题</h1>
		
	</body>

</html>

上面的HTML转换为DOM树形结构:
在这里插入图片描述

  • 当浏览器通过HTML渲染出节点的同时,就会生成一个文档对象,主要功能是处理网页内容。

2.节点的类型

  • 节点至少拥有nodeType、nodeName和nodeValue这三个基本属性。节点类型不同,这三个属性的值也不相同。
    1. nodeType属性返回节点类型的常数值。不同的类型对应不同的常数值,12种类型分别对应1到12的常数值
    2. nodeName属性返回节点的名称。
    3. nodeValue属性返回或设置当前节点的值,格式为字符串。

节点共有12种类型

元素节点   Node.ELEMENT_NODE(1)
属性节点   Node.ATTRIBUTE_NODE(2)
文本节点   Node.TEXT_NODE(3)
CDATA节点 Node.CDATA_SECTION_NODE(4)
实体引用名称节点    Node.ENTRY_REFERENCE_NODE(5)
实体名称节点   Node.ENTITY_NODE(6)
处理指令节点   Node.PROCESSING_INSTRUCTION_NODE(7)
注释节点   Node.COMMENT_NODE(8)
文档节点   Node.DOCUMENT_NODE(9)
文档类型节点   Node.DOCUMENT_TYPE_NODE(10)
文档片段节点   Node.DOCUMENT_FRAGMENT_NODE(11)
DTD声明节点 Node.NOTATION_NODE(12)

主要介绍三种常用节点
  1. 元素节点
      元素节点element对应网页的HTML标签元素。元素节点的节点类型nodeType值是1,节点名称nodeName值是大写的标签名,nodeValue值是null

  2. 特性节点
      元素特性节点attribute对应网页中HTML标签的属性,它只存在于元素的attributes属性中,并不是DOM文档树的一部分。特性节点的节点类型nodeType值是2,节点名称nodeName值是属性名,nodeValue值是属性值

  3. 文本节点
      文本节点text代表网页中的HTML标签内容。文本节点的节点类型nodeType值是3,节点名称nodeName值是’#text’,nodeValue值是标签内容值

3.节点间的关系

  • 节点之间的关系可以类比为父子和兄弟间的关系。

在这里插入图片描述

属性
  • 每个节点都有一个parentNode属性,该属性指向文档树中的父节点。对于一个节点来说,它的父节点只可能是三种类型:element节点、document节点和documentfragment节点。如果不存在,则返回null
<div id="myDiv"></div>
<script>
let myDiv = document.getElementById('myDiv');
console.log(myDiv.parentNode);//body
let fragment = document.createDocumentFragment();
fragment.appendChild(myDiv);
console.log(myDiv.parentNode);//document-fragment
console.log(document.parentNode); //null
</script>
  • parentElement仅返回父元素节点,在IE浏览器中,只有Element元素节点才有该属性,其他浏览器则是所有类型的节点都有该属性
<script>
console.log(document.documentElement.parentNode);//document
console.log(document.documentElement.parentElement);//null
</script>
  • childNodes是一个只读的类数组对象NodeList对象,它保存着该节点的第一层子节点
<ul id="myUl">
	<li>
		<div></div>
	</li>
</ul>
<script>
let myUl = document.getElementById('myUl');
//结果是只包含一个li元素的类数组对象[li]
console.log(myUl.childNodes);
</script>
  • children是一个只读的类数组对象HTMLCollection对象,但它保存的是该节点的第一层元素子节点
<div id="myDiv">123</div>
<script>
let myDiv = document.getElementById('myDiv');
//childNodes包含所有类型的节点,所以输出[text]
console.log(myDiv.childNodes);
//children只包含元素节点,所以输出[]
console.log(myDiv.children);
</script>
  • childElementCount返回子元素节点的个数,相当children.length,IE8-浏览器没有该属性
<ul id="myUl">
    <li></li>
    <li></li>
</ul>
<script>
let myUl = document.getElementById('myUl');
console.log(myUl.childNodes.length);//5,包括了3个回车符生成的空文本节点
console.log(myUl.children.length);//2
console.log(myUl.childElementCount);//2,IE8-浏览器返回undefined
</script>
  • firstChild获取第一个子节点
  • lastChild获取最后一个子节点
  • firstElementChild获取第一个元素节点
  • lastElementChild获取最后一个元素节点

IE8不支持firstElementChild和lastElementChild,且不会识别空白文本节点

<ul id="list">
    <li>1</li>
    <li>2</li>
    <li>3</li>
</ul>
<script>
let list = document.getElementById('list');
console.log(list.firstChild);//标准浏览器中返回空白文本节点,IE8-浏览器中返回<li>1</li>
console.log(list.lastChild);//标准浏览器中返回空白文本节点,IE8-浏览器中返回<li>3</li>
console.log(list.firstElementChild);//标准浏览器中<li>1</li>,IE8-浏览器中返回undefined
console.log(list.lastElementChild);//标准浏览器中<li>3</li>,IE8-浏览器中返回undefined
</script>

同级属性

  • nextSibling返回目标节点后一个节点。
  • previousSibling返回目标节点前一个节点。
  • nextElementSibling返回目标节点后一个元素节点。
  • previousElementSibling返回目标节点前一个元素节点。

*同样,IE8不识别空白文本节点,且不支持nextElementSibling和previousElementSibling

方法
  • hasChildNodes()用于判断目标节点是否存在子节点,如果存在,返回true
<div id="myDiv">123</div>
<script>
var myDiv = document.getElementById('myDiv');
console.log(myDiv.hasChildNodes());//true
</script>
  • contains()方法接受一个节点作为参数,返回一个布尔值,表示参数节点是否为当前节点的后代节点(包括自身)。参数为后代节点即可,不一定是第一层子节点
<div id="myDiv">
    <ul id="myUl">
        <li id="myLi"></li>
        <li></li>
    </ul>
</div>
<script>
let myDiv = document.getElementById('myDiv');
let myLi = document.getElementById('myLi');
let myUl = document.getElementById('myUl');
console.log(myDiv.contains(myLi));//true
console.log(myDiv.contains(myUl));//true
console.log(myDiv.contains(myDiv));//true
</script>
  • compareDocumentPosition()用于确定节点间的关系,返回一个表示该关系的位掩码。

000000 0 两个节点相同
000001 1 两个节点不在同一个文档(即有一个节点不在当前文档)
000010 2 参数节点在当前节点的前面
000100 4 参数节点在当前节点的后面
001000 8 参数节点包含当前节点
010000 16 当前节点包含参数节点
100000 32 浏览器的私有用途

  • isSameNode()接受一个节点参数,如果当前节点和参数节点是同一个,则返回true。
  • isEqualNode()接受一个节点参数,如果当前节点和参数节点,具有相等的属性(nodeName、nodeValue等等),而且它们的attributes和childNodes属性也相等(相同位置包含相同的值),则返回true。
<script>
var div1 = document.createElement('div');
div1.setAttribute("title","test");
var div2 = document.createElement('div');
div2.setAttribute("title","test");
console.log(div1.isSameNode(div1));//true
console.log(div1.isEqualNode(div1));//true
console.log(div1.isEqualNode(div2));//true
console.log(div1.isSameNode(div2));//false
</script>

4.节点的操作

插入节点
  • appendChild() 用于在调用节点的子节点列表的最后插入一个新的子节点。更新完成后,会返回新增的节点。
<body>
  <ul id="myUl">
    <li>1</li>
    <li>2</li>
  </ul>
</body>
<script>
  let myUl = document.getElementById('myUl');
  let newNode = document.createElement('li');//创建一个li元素节点
  let appendNode = myUl.appendChild(newNode);
  console.log(appendNode == newNode); //true
  console.log(myUl.lastChild == newNode); //true
 </script>
  • insertBefore() 如果需要把节点放在子节点列表的某个特定位置时使用,可以接受两个参数:插入的节点和参照节点,调用之后插入节点会变成参照节点的前一个节点,同时被方法返回。
<body>
  <ul id="myUl">
    <li>1</li>
    <li>2</li>
  </ul>
</body>
<script>
  let myUl = document.getElementById('myUl');
  let newNode = document.createElement('li');//创建一个li元素节点
  let appendNode = myUl.insertBefore(newNode, myUl.lastChild);//将li节点插入到倒数第二个子元素节点位置
  console.log(appendNode == newNode); //true
  console.log(newNode == myUl.childNodes[myUl.childNodes.length - 2]); //true
</script>
移除节点
  • removeChild() 方法接受一个节点作为参数,移除该节点的同时,返回该节点。
  • replaceChild() 方法接受两个参数,分别是要插入的节点和要替换的节点,方法会返回被替换的节点。
<body>
  <ul id="myUl">
    <li>1</li>
    <li>2</li>
  </ul>
</body>
<script>
  let myUl = document.getElementById('myUl');
  let newNode = document.createElement('li');//创建一个li元素节点
  let appendNode = myUl.replaceChild(newNode, myUl.lastChild);//替换最后一个空文本节点
  console.log(appendNode); //回车符形成的空文本节点
  console.log(newNode == myUl.childNodes[myUl.childNodes.length - 1]); //true
</script>
其他方法

下面两个方法是所有类型的节点都有的

  • cloneNode() 用来复制一个调用该方法的节点的副本,方法接受一个boolean值作为参数,为true时执行深拷贝,会复制节点以及节点的整个子节点树,值为false时,只复制节点本身。复制后的节点不会保留父节点关系。
<body>
  <ul id="myUl">
    <li>1</li>
    <li>2</li>
  </ul>
</body>
<script>
  let myUl = document.getElementById('myUl');
  let deep = myUl.cloneNode(true);
  let shallow = myUl.cloneNode(false);
  console.log(deep.childNodes.length); //5(IE8为2)
  console.log(shallow.childNodes.length); //0
  console.log(deep.parentNode); //null
 </script>
  • normalize() 方法移除空的文本节点,并连接相邻的文本节点。

4.动态创建

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值