* 什么是DOM
DOM 是 Document Object Model(文档对象模型)的缩写, 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容、结构和样式;
DOM 标准被分为 3 个不同的部分:
- 核心 DOM - 针对任何结构化文档的标准模型。
- XML DOM - 针对 XML 文档的标准模型。定义了所有 XML 元素的对象和属性,以及访问它们的方法
- HTML DOM - 针对 HTML 文档的标准模型。 定义了所有 HTML 元素的对象和属性,以及访问它们的方法
这里我们只讲HTML DOM。
* HTML DOM 树
HTML DOM 将 HTML 文档视作树结构。这种结构被称为节点树:
通过 HTML DOM,树中的所有节点均可通过 JavaScript 进行访问。所有 HTML 元素(节点)均可被修改,也可以创建或删除节点.
那么,什么是节点?
在 HTML DOM 中,所有事物都是节点。
- 整个文档就是一个文档节点。
<html>...</html>
- 每个HTML元素是元素节点。
<head>...</head>
或<body>...</body>
或<div>...</div>
- HTML元素内部的文本是文本节点 / TextNode。
<p>hello world</p>
中的hello world
- 每个HTML属性是属性节点。
<div class="mystyle"></div>
中的class
- 注释是注释节点。
例子: <title>你好!</title>,元素节点 <title>,包含值为 "你好!" 的文本节点。
* HTML DOM 对象 - 方法和属性
方法 是我们可以在节点上执行的动作(比如添加或修改元素),属性 是我们能够获取或设置的值(比如节点的名称或内容)。
常用的 HTML DOM 方法:
-
getElementById(id) - 获取带有指定 id 的节点(元素)
var ele = document.getElementById("eleId");
-
appendChild(node) - 插入新的子节点(元素)
ele.appendChild(sub);
-
removeChild(node) - 删除指定的子节点(元素)
ele.removeChild(sub);
- insertBefore(node) - 在指定的子节点前面插入新的子节点(元素);相对兄弟元素定位
-
getAttribute("id") - 返回指定的属性值
ele.getAttribute("id");
-
setAttribute("id") - 把指定属性设置或修改为指定的值
ele.setAttribute("disabled") = "true";
- getElementsByTagName() - 返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)
- getElementsByClassName() - 返回包含带有指定类名的所有元素的节点列表
- replaceChild() - 替换子节点
- createAttribute() - 创建属性节点;为一个元素增加一个属性
- createElement() - 创建元素节点
- createTextNode() - 创建文本节点
常用的HTML DOM属性:
-
innerHTML - 节点(元素)的文本值
var text = ele.innerHTML
-
parentNode - 节点(元素)的父节点
var eleParent = ele.parentNode
父节点只有一个,没有s -
childNodes - 节点(元素)的子节点
var eleChild = ele.childNodes
子节点有可能有多个,带s -
attributes - 节点(元素)的属性节点
var attr - ele.attributes
获取dom属性列表
我做了实验,发现非常有意思的信息:
html代码
<div class="box" id="box">
<div class="main" id="main"></div>
<div class="sub" id="sub">nihao</div>
</div>
css代码
* {margin: 0px; padding: 0px;}
.box {
width: 300px;
height: 300px;
background-color: #c688e3;
margin: 0 auto;
position: relative;
}
.main {
width: 100px;
height: 100px;
margin: 0 auto;
background: #40cfee;
}
.sub {
width: 100px;
height: 100px;
margin-top: 100px;
position: absolute;
background-color: pink;
}
javascript代码
var box = document.getElementById("box");
var main = document.getElementById("main");
var sub = document.getElementById("sub");
// main.appendChild(sub);
// main.removeChild(sub);
console.dir(box.childNodes);
// console.dir(sub.attributes);
效果图
main
和sub
在box
包含框中按文档普通流规则正常显示。
sub
被appendChild
到main
内部,作为main
的子元素而存在。注意,此时sub
是在文档普通流中提出来之后加入到main
中的,作为main
的兄弟节点的sub已经被提走了。
可以看到,sub
节点没了,虽然他作为子元素本身存在与在box
包含框中,但经过appendChild
和removeChild
之后,该节点已经被删除。
惊了,居然length
为5!为什么长度为5?细细看来发现,第0/2/4
都为text
,并且打开看发现值是 回车键,明白了吧,原因就是我们在编程时习惯给格式化,对代码进行换行显示,这个换行符其实就是个不可见文本,dom
会将其当做子元素了,所以长度为5。所以平时我们在使用的时候一定要注意,并且也可以用这种方式获取文本内容。
这个没什么问题,就是正常的将属性抓取出来,放到一个数组当中而已。
innerHtml属性
innerHTML
属性对于获取或替换 HTML 元素的内容(文本节点)
html代码
<html>
<body>
<p id="intro">Hello World!</p>
</body>
</html>
css代码
#intro {
display: none;
}
javascript代码
var txt=document.getElementById("intro").innerHTML;
document.write(txt);
效果展示
将javascript代码改一下,如下
javascript代码
document.getElementById("intro").innerHTML = "haha, is me";
var txt=document.getElementById("intro").innerHTML
document.write(txt)
效果展示
nodeName属性
nodeName
属性规定节点的名称,并且,nodeName
始终包含 HTML 元素的大写字母标签名
- nodeName 是只读的
- 元素节点的 nodeName 与标签名相同
- 属性节点的 nodeName 与属性名相同
- 文本节点的 nodeName 始终是 #text
- 文档节点的 nodeName 始终是 #document
nodeValue 属性
nodeValue
属性规定节点的值
-元素节点的 nodeValue 是 undefined 或 null
-文本节点的 nodeValue 是文本本身
-属性节点的 nodeValue 是属性值 document.getElementById("main").nodeValue
输出 null
html代码
<html>
<body>
<p id="intro">Hello World!</p>
</body>
</html>
css代码
#intro {
display: none;
}
js代码
var txt = document.getElementById('intro').nodeValue;
var f = txt == undefined
document.write(f)
效果展示
页面代码
<html>
<body>
<p id="intro">Hello World!</p>
<script>
x=document.getElementById("intro");
document.write(x.firstChild.nodeValue);
</script>
</body>
</html>
输出
nodeType 属性
nodeType 属性返回节点的类型,在我们爬数据的时候可能会用到。重要的有以下几种:
元素类型 | nodeType |
---|---|
元素 | 1 |
属性 | 2 |
文本 | 3 |
注释 | 8 |
文档 | 9 |
* HTML DOM 访问
访问HTML元素,就是访问HTML 节点,三种方法:
-
getElementById() 方法
document.getElementById("intro");
返回带有指定 ID 的元素 -
getElementsByTagName() 方法
document.getElementsByTagName("p");
返回带有指定标签名的所有元素 -
getElementsByClassName() 方法
document.getElementsByClassName("intro");
返回带有相同类名的**所有 **HTML 元素
getElementsByClassName() 在 Internet Explorer 5,6,7,8 中无效。
* HTML DOM 修改
修改 HTML DOM 意味着许多不同的方面
-
改变 HTML 内容
document.getElementById("p1").innerHTML="New text!";
改变一个 <p> 元素的 HTML 内容 -
改变 CSS 样式
document.getElementById("p2").style.color="blue";
改变一个<p>元素 文字的颜色 - 改变 HTML 属性
-
创建新的 HTML 元素
见下方
- 替换已有的 HTML 元素 ```见下方``
- 删除已有的 HTML 元素
-
改变事件(处理程序)
见下方
创建新的 HTML 元素(1)
如需向 HTML DOM 添加新元素,您首先必须创建该元素(元素节点),然后把它追加到已有的元素上。
html代码
<div id="d1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
javascript代码
var para=document.createElement("p"); // 创建<p>元素节点
var node=document.createTextNode("This is new."); // 给空的<p>元素节点增加文本节点"this is new"
para.appendChild(node); // 生成带有文本子节点的<p>元素节点
var element=document.getElementById("d1");
element.appendChild(para); // 追加<p>元素节点到d1中
页面展示
上面的代码是将新元素添加到最后一个子节点后面的,如果我们不希望如此,也可以用insertBefore() 实现;
创建新的 HTML 元素(2)
这里涉及到三个元素节点,父元素,新元素和某个兄弟元素。
html代码
<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
javascript代码
var para=document.createElement("p"); // 创建<p>元素节点
var node=document.createTextNode("This is new."); // 给空的<p>元素节点增加文本节点"this is new"
para.appendChild(node); // 生成带有文本子节点的<p>元素节点
var element=document.getElementById("div1"); // 查找父节点的元素节点
var child=document.getElementById("p1"); // 查找插入位置的元素节点
element.insertBefore(para,child); // 将para元素节点插入child元素节点之前
替换 HTML 元素replaceChild()
html代码
<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
javascript代码
var para=document.createElement("p");
var node=document.createTextNode("This is new.");
para.appendChild(node);
var parent=document.getElementById("div1");
var child=document.getElementById("p1");
parent.replaceChild(para,child); // 使用replaceChild()替换
使用事件修改dom元素
HTML DOM 允许您在事件发生时执行代码;当 HTML 元素”有事情发生“时,浏览器就会生成事件:
- 在元素上点击
- 加载页面
- 改变输入字段
html代码
<html>
<body>
<input type="button" onclick="ChangeBackground()" value="Change background color" />
</body>
</html>
js代码
function ChangeBackground()
{
document.body.style.backgroundColor="lavender";
}
效果展示
* HTML DOM 事件
HTML DOM 允许 JavaScript 对 HTML 事件作出反应,当事件发生时,可以执行 JavaScript。
HTML 事件的例子:
-
当用户点击鼠标时
onclick="doIt()"
;鼠标按下onmousedown
;鼠标弹起onmouseup
。首先当某个鼠标按钮被点击时,触发 onmousedown 事件,然后,当鼠标按钮被松开时,会触发 onmouseup 事件,最后,当鼠标点击完成时,触发 onclick 事件 -
当网页已加载时
onload="doIt()"
;离开网页时使用onunload="doIt()"
;onload
事件可用于检查访客的浏览器类型和版本,以便基于这些信息来加载不同版本的网页。onload
和onunload
事件可用于处理cookies
- 当图片已加载时
-
当鼠标移动到元素上时
onmouseover=”doIt()“
;鼠标移开onmouseout=”doIt()“
-
当输入字段被改变时
onchange="doIt()"
常用于输入字段的监控,验证。 - 当 HTML 表单被提交时
- 当用户触发按键时
我们也可以使用 HTML DOM 来分配事件:
该例为 button 元素分配 onclick 事件:
javascript代码
document.getElementById("myBtn").onclick=function(){
displayDate()
};
用onload来处理cookies
html代码
<html>
<body onload="checkCookies()">
<p>弹出的提示框会告诉你浏览器是否已启用 cookie。</p>
</body>
</html>
javascript代码
function checkCookies() {
if (navigator.cookieEnabled==true) {
alert("Cookies are enabled")
} else {
alert("Cookies are not enabled")
}
}
* HTML DOM - 导航
1. HTML DOM 节点列表
getElementsByTagName() 方法返回节点列表数组
下面的代码选取文档中的所有 <p> 节点:
var x=document.getElementsByTagName("p");
可以通过下标号访问这些节点。如需访问第二个 <p>,您可以这么写:
var y=x[1]; // 下标从0开始
length 属性定义节点列表中节点的数量
var len = x.length
简单应用: 获取所有 <p> 元素节点,并输出每个 <p> 元素的文本节点的值
x=document.getElementsByTagName("p");
for (i=0;i<x.length;i++) {
document.write(x[i].innerHTML);
document.write("<br />");
}
2. 导航节点关系
您能够使用三个节点属性:parentNode、firstChild 以及 lastChild ,在文档结构中进行导航。
<html>
<body>
<p>Hello World!</p>
<div>
<p>DOM 很有用!</p>
<p>本例演示节点关系。</p>
</div>
</body>
</html>
观察上述结构
- 首个 <p> 元素是 <body> 元素的首个子元素(firstChild)
firstChild 属性可用于访问元素的文本,前面我们用过
- <div> 元素是 <body> 元素的最后一个子元素(lastChild)
- <body> 元素是首个 <p> 元素和 <div> 元素的父节点(parentNode)
3. DOM 根节点
这里有两个特殊的属性,可以访问全部文档:
- document.documentElement - 全部文档
-
document.body - 文档的主体
页面的<body>部分
html代码
<html>
<body>
<p>Hello World!</p>
<div>
<p>DOM 很有用!</p>
<p>本例演示 <b>document.body</b> 属性。</p>
</div>
</body>
</html>
javascript代码
alert(document.body.innerHTML);
效果展示
4. childNodes 和 nodeValue
html代码
<html>
<body>
<p id="intro">Hello World!</p>
</body>
</html>
javascript代码
var txt=document.getElementById("intro").childNodes[0].nodeValue;
document.write(txt);
效果展示
* 结束语
至此,HTML DOM 内容已经结束,如果理解还不够透彻,你可以猛戳这里查看更多DOM实例