HTML DOM 探索
2017年2月10日20:54:11 CHJ_1993
1、前言
因为最近比较忙,好久没有写博客了,记得我第一篇自我介绍的博客说经常给大家分享一些我学习的知识,但是时间过去这么久了,也没有更新几篇本章,可能刚开始写的文章也很烂。作为博客新手,希望大家原谅一下。
今天有点时间, 我就来跟大家探讨一下 HTML DOM 的一些知识。好了下面开始正文.....
2、DOM的概念
DOM 是 (Document Object Model) 的缩写
- DOM 是针对 XML 和 HTML 文档的一个 api (应用程序接口)
- DOM 中描述了一个层级化的节点树
- DOM 中允许开发人员对页面的某一部分内容进行修改,移除,添加
W3C 中 DOM标准化分类分成三种:
- 核心 DOM ==== 针对任何结构化文档的标准模型
- XML DOM ==== 针对XML文档的标准模板
- HTML DOM ==== 针对HTML 文档的标准模板
DOM标准分化分为三种,那么前面两种我们今天不进行探索,我们今天主要来了解的是HTML DOM
3、HTML DOM 的探索
3.1 什么是HTML DOM ?
HTML DOM 是HTML的标准对象模型,也是HTML的标准编程接口
HTML DOM 定义了所有HTML元素的对象 ** 和 属性,以及访问他们的方法**
换句话说, HTML DOM 是关于如何获取、修改、添加或者删除HTML元素的标准
3.2 HTML DOM的节点
根据W3C(万维网) 的HTML DOM标准,HTML文档中所有的内容都是节点
- 整个文档 是一个文档节点
- 每个HTML元素都是元素节点
- HTML 元素内的文本是文本节点
- 每个 HTML 属性是属性节点
- 注释是注释节点
下面我们引用网上的一张图来描述一下: (HTML DOM 的节点树结构)
3.2.1 HTML DOM 节点分类
HTML DOM 中个一共存在12 个节点类型,任何一个节点类型都属于这12个节点类型之一
如下表:
属性名称 | 代表中文含义 |
---|---|
Node.ELEMENT_NODE | 元素 |
Node.ATTRIBUTE_NODE | 元素中的属性 |
Node.TEXT_NODE | 纯文本(没有子节点) |
Node.CDATA_SECTION_NODE | 子节点是TextNode |
Node.ENTITY_REFERENCE_NODE | 文档中的实体引用 |
Node.ENTITY_NODE | DTD中的实体定义 |
Node.PROCESSING_INSTRUCTION_NODE | 一个文档处理程序中使用的特有指令 |
Node.COMMENT_NODE | 注释 |
Node.DOCUMENT_NODE | 最外层的 (根节点) |
Node.DOCUMENT_TYPE_NODE | 文档类型定义 |
Node.DOCUMENT_FRAGMENT_NODE | 更小型的Docment 的节点,定义整个数据类型主要是为了方便只希望提取文档的某一部分时使用 |
Node.NOTATION_NODE | DTD 的Nation定义 |
3.2.2 HTML DOM 文档节点的属性
文档节点的属性,我们今天主要认识的就只有三个:
-
nodeName
节点名称,只读
-
nodeValue
节点的值 ,可读可写
-
nodeType
节点的类型,只读
3.3 HTML DOM 核心对象 document 对象
在JavaScript中 是通过Document 来表示文档的,Document 的属性如下:
- document的节点类型 (nodeType) 为 9
- document 的节点名称 (nodeName) 是 #document
- document 的节点值(nodeValue) 为空(null)
- document 是没有父节点(parentNode) 的
- document 也没有根元素(ownerDocument)
3.3.1 通过document 来获取 元素(节点)
在JavaScript 获取元素的方式主要有以下中方法
- document.getElementById() 通过ID的方式来获取元素.
- document.getElementsByTagName() 根据标签名来获取元素
- document.getElementsByName() 通过标签的name属性的值来获取元素
- document.getElementsByClassName() 通过class 的属性值来获取元素
- querySelector() 通过选择器名称来获取元素(获取匹配到的第一个)
- querySelectorAll() 通过选择器名称来获取元素(获取全部)
3.3.1.1 document.getElementById()
通过元素中ID属性的属性值来查找元素
语法: node.getElementById("id");
注意:
- 使用该方法不能同时查找多个ID
- 如果有HTML中有相同ID,则只会返回一个元素
- 在 低于 IE 8 版本的IE浏览器中,对匹配元素的ID,该方法不区分大小写
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h1 id="h1">我是标题</h1>
</body>
<script type="text/javascript">
var eH1 = document.getElementById("h1");
alert(eH1.innerHTML);
</script>
</html>
3.3.1.2 document.getElementsByTagName()
根据标签名来获取元素
语法: node.getElementsByTagName(标签名称)
返回值: 返回多个同标签名的Element组成的集合
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1 id="myH1" class="myH1class">我是H1标签</h1>
<h1 id="myH2" class="myH1class">我是H1标签</h1>
<h1 id="myH3" class="myH1class">我是H1标签</h1>
<h1 id="myH4" class="myH1class">我是H1标签</h1>
</body>
<script>
var h1_ls = document.getElementsByTagName("h1");
console.log(h1_ls);
for (var i = 0; i < h1_ls.length; i++) {
console.log(h1_ls[i].id); //元素的ID
console.log(h1_ls.item(i).id); //通过元素的Item 来获取Item内容
}
</script>
</html>
3.3.1.3 document.getElementsByName()
通过标签的name属性的值来获取元素,可能出现
语法: docuemnt.getElementsByName("name属性值");
返回值: 返回多个相同的name值的Element组成的集合
注意: 该方法存在严重的兼容性问题,在IE中,此方法还能获取ID属性匹配的值
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form action="" method="get">
<input type="checkbox" name="input_name" value="洗澡" />洗澡
<input type="checkbox" name="input_name" value="喝水" />喝水
</form>
</body>
<script type="text/javascript">
var names = document.getElementsByName('input_name');
for (var i = 0; i<names.length; i++) {
console.log(names[i].value);
}
</script>
</html>
3.3.1.4 document.getElementsByClassName()
通过相同的class属性的值来获取元素
语法: document.getElementsByClassName(class属性值);
返回值: 返回多个相同的class属性值的Element组成的集合
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h1 id="myH1" class="myH1class">我是H1标签</h1>
<h2 id="myH2" class="myH1class">我是H2标签</h1>
<h3 id="myH3" class="myH1class">我是H3标签</h1>
<h4 id="myH4" class="myH1class">我是H4标签</h1>
</body>
<script type="text/javascript">
var myClassLi = document.getElementsByClassName('myH1class');
for (var i = 0; i<myClassLi.length; i++) {
console.log(myClassLi[i].value);
}
</script>
</html>
3.3.1.4 querySelector()
通过CSS 选择器的放来来获取元素,
指定一个或者多个匹配的CSS选择器,id,class, 类型,属性
如果针对多个选择器,中间使用d"逗号分隔",
语法: document.querySelector("#demo")
返回值: 直接返回匹配到的第一个元素,如果没有找到则返回null
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<p id="demo"></p>
</body>
<script type="text/javascript">
var p_1 = document.querySelector("#demo");
console.log(p_1);
</script>
</html>
3.3.1.4 querySelectorAll()
HTML5引入的一种新的查找元素的方法
语法: document.querySelectorAll(".p_1")
返回值: 返回查找到的所有相同选择器的Element 集合
注意: 该方法不是实时返回的,只有调用的时候才会返回,因为这样开发人员通常可以利用伪类选择器( :hover , :visited ) 去访问用户的浏览习惯等,所以现在很多浏览器不支持该方法
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div class="p_1"></div>
<div class="p_1"></div>
<div class="p_1"></div>
</body>
<script type="text/javascript">
var all = document.querySelectorAll(".p_1");
console.log(all)
</script>
</html>
好了,说了上面一大推,篇幅有点长了,但是我觉得我还是要继续把下面几点说完
上面说了元素的获取的几种方法,那么现在我们可以获取到元素了,那么元素和元素之间的关系又是怎么样的? 那么下面我们来说 元素节点之间的关系
3.3.2 HTML DOM 中节点的关系
我们学过HTML 的都知道 HTML元素之间的关系 有父子关系,和兄弟关系(同级元素)
那么在DOM中节点关系有以下几种
- parent 父节点
- child子节点
- sibling 兄弟节点(同级节点)
- root 根节点
如图所示:
-
父节点属性(parentNode)
获取一个元素的父节点
语法:
node.parentNode
-
兄弟节点属性(sibling)
同级节点属性又分为两个小的属性:
上一个同级节点(previousSibling)
获取某个元素的上一个同级节点
语法:
node.previousSibling
下一个同级节点(nextSibling)
获取某个元素的下一个同级节点
语法
node.nextSibling
因为在使用者两种方法获取到,可能含有
<div> </div>
中间的空格,又因为JavaScript 是一种弱类型语言,就衍生了下面的两种方法: 上一个同级元素(previousElementSibling)
获取某个元素的上一个同级元素
语法:
node.previousElementSibling
下一个同级元素(nextElementSibling)
获取某个元素的下一个同级元素
语法
node.nextElementSibling
-
根节点 ( ownerDocument)
获取某个元素的根元素
语法:
node.ownerDocument
获取一个元素的根节点
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="demo">
<a href="###">搜狐</a><div id="div">DIV</div><div>
<a href="#"></a>
</div>
<input type="text" />
</div>
</body>
<script type="text/javascript">
//parentNode 获取父节点
var div = document.getElementById("demo");
div.previousSibling;
console.log(div.parentNode.nodeName); //BODY
//previousSibling 获取元素的上一个同级节点
var div1 = document.getElementById("div");
var preSib= div1.previousSibling;
console.log(preSib);
//previousElementSibling 获取元素的上一个同级节点
var preSib2= div1.previousElementSibling;
console.log(preSib2);
//nextSibling 获取元素的下一个同级节点
var nextElement = div1.nextSibling;
console.log(nextElement)
//nextElementSibling 获取元素的下一个同级节点
var nextElement2 = div1.nextElementSibling;
console.log(nextElement2)
//ownerDocument 获取元素的根节点
var rootElement = div1.ownerDocument;
console.log(rootElement)
</script>
</html>
-
子节点属性(ChildNodes)
在这里要写的是三个小属性
所有子节点(ChildNodes)
用来获取一个元素的所有子节点
返回值: 一个数组,只获取子节点,不能获取子节点的子节点
语法:
node.chilNodes
第一个子节点(firstChild)
获取元素的第一个子节点 ,如果匹配不到则返回null
语法:
node.firstChild
最后一个子节点(lastChild)
获取元素的最后一个子节点 ,如果匹配不到则返回null
语法
node.lastChild
因为在使用者两种方法获取到,可能含有
<div> </div>
中间的空格,又因为JavaScript 是一种弱类型语言,就衍生了下面的两种方法: 第一个子元素(firstElementChild)
获取某个元素的第一个子元素
语法:
node.firstElementChild
最后一个子元素(lastElementChild)
获取某个元素的最后一个子元素
语法
node.lastElementChild
代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <div id="demo"> <a href="###">简书</a> <a href="###">百度</a> <div> <a href="###">博客</a> </div> <input type="text" name="input_name" id="input" value="" /> </div> </body> <script type="text/javascript"> //获取元素的所有子节点 var nodes = document.getElementById("demo").childNodes; console.log(nodes); for (var i = 0;i<nodes.length; i++) { console.log(nodes[i].nodeName); } //获取所有子元素的个数 var nodes = document.getElementById("demo").childElementCount; console.log(nodes); //firstChild 获取元素的第一个子节点 var div = document.getElementById("demo"); var firstChlid = div.firstChild; console.log(firstChild); console.log(firstChild.nodeName); //firstElementChild 获取元素的第一个子节点 var firstChild2 = div.firstElementChild; console.log(firstChild2); console.log(firstChild2.nodeName); //firstChild 获取元素的第一个子节点 var div = document.getElementById("demo"); var lastCh = div.lastChild; console.log(lastCh); console.log(lastCh.nodeName); //firstElementChild 获取元素的第一个子节点 var lastChild = div.lastElementChild; console.log(lastChild); console.log(lastChild.nodeName); </script> </html>
有比比了好久,说了那么多的元素之间的关系,那么我们平时获取元素,不仅仅只是想获取到他的一下属性,了解他的关系吧,同样我们有事需要对元素进行操作,那么下面我们来说说对Node节点的操作
3.3.2 HTML DOM 中节点增加 删除 修改 创建
由于文章篇幅比较长了,大家也是不想看到我说一大推的废话了 那么我下面直接贴出代码 给大家看 在代码中我也是注释的比较清楚,以后再来修改
代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="demo">
</div>
<ul id="language">
<li>Java</li>
<li>C#</li>
</ul>
<button onclick="addNode()">点击添加一个新的首节点</button>
<button onclick="removeNode()">删除一个子节点</button>
<button onclick="replaceNode()">替换首节点</button>
<button onclick="cloneNodes()">克隆整个列表</button>
</body>
<script type="text/javascript">
/*
修改
* 1.创建文本节点
* createTextNode(text)
* 参数: text 文本
* 返回值: 创建的文本标签
* 该方法属于 document 的
* 2.添加一个子节点
* addpendChild(node)
* 参数:
* node: 必选参数,需要添加的节点
* 返回值: 参数对象本身
* 翻译过来时追加,如果本身已经有child ,则追加到child之后
* 添加进去就是 lastChild
* 3.创建新的元素节点
* createElement(nodeName)
* 参数:
* nodeName: 需要创建的元素名称
* 返回值: 创建的元素节点
* 4.在节点之前加入新的节点
* insertBefor(newNode,existingNode)
* 参数:
* newNode:需要插入的新节点
* existingNode: 当前插入的目标节点
* 会将新节点插入到目标节点之前
* 5.移除一个子节点
* removeChild(node)
* 参数:
* node:必选参数,表示需要移除的子节点
* 6.替换一个子节点
* replaceChild(newNode,oldNode)
* 参数:
* newNode: 新节点
* oldNode: 旧的节点
* 7.克隆节点
* 该方法用于创建指定的节点的精准拷贝所有的属性和属性值
* cloneNode(deep)
* 参数:
* deep: true/ false
* true: 将递归复制当前节点的所有节点
* false: 只复制当前节点
*/
var divDemo = document.getElementById("demo");
//======创建一个文本节点====
var textNode = document.createTextNode("hello world");
console.log(textNode.nodeName); // #text
console.log(textNode.nodeValue); // hello world
//=====添加一个文本节点===
var appendNode = divDemo.appendChild(textNode);
console.log(appendNode.nodeValue); //hello world
//===== 创建元素节点====
var newElement = document.createElement("a");
var newElementText = document.createTextNode("新建的元素内容");
newElement.appendChild(newElementText);
var divDemo = divDemo.appendChild(newElement);
//====在节点之前加入新的节点===
function addNode(){
var newItem = document.createElement("li"); //创建一个新的li元素
var newItemTextNode = document.createTextNode("Javascript");
newItem.appendChild(newItemTextNode);
var languageList = document.getElementById("language");
//将新创建的Item添加到目标节点之前
languageList.insertBefore(newItem,languageList.firstChild);
}
//=======移除子节点====
function removeNode(){
var languageList = document.getElementById("language");
var li_lsit = languageList.getElementsByTagName("li");
//移除li中的第一个
languageList.removeChild(li_lsit[0]);
}
//============替换子节点=====
function replaceNode(){
var languageList = document.getElementById("language");
var newLi = document.createElement("li");
newLi.innerHTML="node.js"
console.log(newLi.value);
languageList.replaceChild(newLi,languageList.firstElementChild);
}
//==========克隆节点===========
function cloneNodes(){
var languageList = document.getElementById("language");
var newList = languageList.cloneNode(false);
document.getElementsByTagName("body")[0].appendChild(newList);
}
</script>
</html>
好了 看到这里 我的文章也就结束了,感谢您的浏览!
你们的支持,就是我前进的动力