DOM 简介
DOM 对象
DOM,全称是“Document Object Model(文档对象模型)”,它是由 W3C 定义的一个标准。简单地说,DOM 里面有很多方法,我们可以通过它提供的方法来操作一个页面中的某个元素,如改变这个元素的颜色、点击这个元素实现某些效果、直接把这个元素删除等。一句话总结:DOM 操作,可以简单地理解成“元素操作”。
DOM 结构
DOM 采用的是“树形结构”,用“树节点”的形式来表示页面中的每一个元素。
为了更好地给每一个元素定位,以便让我们找到想要的元素,把一个HTML页面用树形结构来表示。
每一个元素就是一个节点,而每一个节点就是一个对象。也就是说,我们在操作元素时,其实就是把这个元素看成一个对象,然后使用这个对象的属性和方法来进行相关操作。
节点类型
对于节点类型,需要特别注意以下3点:一个元素就是一个节点,这个节点称为“元素节点”。属性节点和文本节点看起来像是元素节点的一部分,但实际上,它们是独立的节点,并不属于元素节点。只有元素节点才可以拥有子节点,属性节点和文本节点都无法拥有子节点。
获取元素
获取元素,准确地说,就是获取“元素节点(注意不是属性节点或文本节点)”。对于一个页面,我们想要对某个元素进行操作,就必须通过一定的方式来获取该元素,获取该元素后,才能对其进行相应的操作。
这和 CSS 中的选择器相似,只不过选择器是 CSS 的操作方式,而 JavaScript 有属于自己的另一套操作方式。在 JavaScript 中,我们可以通过以下 6 种方式来获取指定元素。
getElementById( )、getElementsByTagName( )、getElementsByClassName( )、querySelector( )和querySelectorAll( )、getElementsByName( )、document.title和document.body。注意大小写。
getElementById( )
类似于 CSS 中的 id 选择器。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oDiv = document.getElementById("div1");
oDiv.style.color = "red";
}
</script>
</head>
<body>
<div id="div1">
JS
</div>
</body>
</html>
window.onload = function(){
...
}
上面这一段代码表示在整个页面加载完成后执行的代码块。浏览器是从上到下解析一个页面的,这个例子的 JavaScript 代码在 HTML 代码的上面,如果没有 window.onload,浏览器解析到 document.getElementById("div1")就会报错,因为它不知道 id 为"div1"的元素究竟是哪一个。
因此我们必须使用 window.onload,这样浏览器会把整个页面解析完了再去解析 window.onload 内部的代码,也就不会报错了。
getElementsByTagName( )
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oUl = document.getElementById("list");
var oLi = oUl.getElementsByTagName("li")
oLi[2].style.color = "red";
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JS</li>
<li>jQuery</li>
</ul>
</body>
</html>
首先使用 getElementById( )方法获取 id 为 list 的 ul 元素,然后使用 getElementsByTagName( )方法获取该 ul 元素下的所有 li 元素。
这里为什么不使用如下代码?
var oLi = document.getElementsByTagName("li");
因为它不同于上述代码,获取的是整个页面中的 li 元素,范围过大。
从上面也可以知道,getElementsByTagName( )方法获取的是一堆元素。实际上这个方法获取的是一个数组,如果我们想得到某一个元素,可以使用数组下标的方式获取。其中,oLi[0] 表示获取第 1 个 li 元素,oLi[1] 表示获取第 2 个 li 元素,……,以此类推。
准确地说,getElementsByTagName( )方法获取的是一个“类数组”(也叫伪数组),它不是真正意义上的数组。对于类数组,我们只能使用数组的 length 属性以及下标的方式,但是对于 push( )、split( )、reverse( )等方法是无法使用的。
两种方式的区别:getElementById( )获取的是 1 个元素,而 getElementsByTagName( )获取的是多个元素(伪数组)。getElementById( )前面只可以接 document,也就是 document.getElementById( )。getElementsByTagName( )前面不仅可以接 document,还可以接其他 DOM 对象。getElementById( )不可以操作动态创建的 DOM 元素,而 getElementsByTagName( )可以操作动态创建的 DOM 元素。
getElementsByClassName( )
和 getElementsByTagName 相似,getElementsByClassName( )获取的也是一个类数组。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oLi = document.getElementsByClassName("select")
oLi[2].style.color = "red";
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li class="select">CSS</li>
<li class="select">JS</li>
<li class="select">jQuery</li>
</ul>
</body>
</html>
querySelector( )和 querySelectorAll( )
JavaScript 新增了两个方法:querySelector( )和querySelectorAll( ),这让我们可以使用 CSS 选择器的语法来获取所需要的元素。
querySelector( )表示选取满足选择条件的第1个元素,querySelectorAll( )表示选取满足条件的所有元素。这两个方法都非常简单,它们的写法和CSS选择器的写法是完全一样的。
document.querySelector("#main")
document.querySelector("#list li:nth-child(1)")
document.querySelectorAll("#list li")
document.querySelectorAll("#input:checkbox")
需要注意的是,querySelectorAll( )方法得到的是一个类数组,即使获取的只有一个元素,也必须使用下标[0]才可以正确获取。
getElementsByName( )
对于表单元素来说,它有一个一般元素都没有的 name 属性。如果想要通过 name 属性来获取表单元素,我们可以使用 getElementsByName( )方法来实现。
getElementsByName( )获取的也是一个类数组,如果想要准确得到某一个元素,可以使用数组下标的方式来获取。getElementsByName( )只用于表单元素,一般只用于单选按钮和复选框。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oInput = document.getElementsByName("status")
oInput[2].checked=true;
}
</script>
</head>
<body>
你的最高学历:
<label><input type="radio" name="status" value="本科">本科</label>
<label><input type="radio" name="status" value="硕士">硕士</label>
<label><input type="radio" name="status" value="博士">博士</label>
</body>
</html>
“oInput[2].checked = true;”表示将类数组中的第 3 个元素的 checked 属性设置为 true,也就是将第 3 个单选按钮选中。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oInput = document.getElementsByName("fruit")
for(var i=0;i<oInput.length;i++){
oInput[i].checked = true;
}
}
</script>
</head>
<body>
你最喜欢的水果:
<label><input type="checkbox" name="fruit" value="苹果">苹果</label>
<label><input type="checkbox" name="fruit" value="香蕉">西瓜</label>
<label><input type="checkbox" name="fruit" value="西瓜">西瓜</label>
</body>
</html>
document.title 和 document.body
由于一个页面只有一个 title 元素和一个 body 元素,因此对于这两个元素的选取,JavaScript 专门提供了两个非常方便的方法:document.title 和 document.body。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
document.title="梦想是什么?";
document.body.innerHTML="<strong style='color:red'>梦想就是让你感到坚持就是幸福的东西</strong>";
}
</script>
</head>
<body>
</body>
</html>
创建元素
在 JavaScript 中,我们可以使用 createElement( )来创建一个元素节点,也可以使用 createTextNode( )来创建一个文本节点,然后可以将元素节点与文本节点“组装”成我们平常看到的“有文本内容的元素”。
这种方式又被称为“动态 DOM 操作”。所谓的“动态 DOM”,指的是使用 JavaScript 创建的元素。这个元素一开始在 HTML 中是不存在的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
var oDiv = document.getElementById("content");
var oStrong = document.createElement("strong");
var oTxt = document.createTextNode("爱学习");
oStrong.appendChild(oTxt);
oDiv.appendChild(oStrong);
}
</script>
</head>
<body>
<div id="content"></div>
</body>
</html>
<script>
window.onload = function(){
var oInput = document.createElement("input");
oInput.id = "submit";
oInput.type = "button";
oInput.value = "提交";
document.body.appendChild(oInput);
}
</script>
已知在 DOM 中,每一个元素节点都被看成一个对象。既然是对象,我们就可以像给对象属性赋值那样,给元素的属性赋值。如想添加一个 id 属性,就可以这样写:oInput.id = "submit"。想添加一个 type 属性,就可以这样写:oInput.type="button",以此类推。
<script>
window.onload = function(){
var oImg = document.createElement("img")
oImg.className = "pic";
oImg.src = "fhn2.jpg";
oImg.style.border = "1px soild silver";
document.body.appendChild(oImg);
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style type="text/css">
table {
border-collapse: collapse;
}
tr,
td {
width: 80px;
height: 20px;
border: 1px solid gray;
}
</style>
<script>
window.onload = function () {
var oTable = document.createElement("table");
for (var i = 0; i < 3; i++) {
var oTr = document.createElement("tr");
for (var j = 0; j < 3; j++) {
var oTd = document.createElement("td");
oTr.appendChild(oTd);
}
oTable.appendChild(oTr);
}
document.body.appendChild(oTable);
}
</script>
</head>
<body>
</body>
</html>
根据上面的几个例子,我们可以总结一下,想要创建一个元素,需要以下4步。① 创建元素节点:createElement( )。② 创建文本节点:createTextNode( )。③ 把文本节点插入元素节点:appendChild( )。④ 把组装好的元素插入到已有元素中:appendChild( )。
插入元素
appendChild
在 JavaScript 中,我们可以使用 appendChild( )把一个新元素插入到父元素的内部子元素的“末尾”。
A.appendChild(B);
A 代表父元素,B 为子元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
var oUl = document.getElementById("list");
var oTxt = document.getElementById("txt");
var textNode = document.createTextNode(oTxt.value);
var oLi = document.createElement("li");
oLi.appendChild(textNode);
oUl.appendChild(oLi);
}
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JS</li>
</ul>
<input type="text" id="txt"><input type="button" id="btn" value="插入">
</body>
</html>
insertBefore
A.insertBefore(B,ref);
A 表示父元素,B 为新插入的子元素,ref 表示要将新的元素插入到 ref 之前。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
var oUl = document.getElementById("list");
var oTxt = document.getElementById("txt");
var textNode = document.createTextNode(oTxt.value);
var oLi = document.createElement("li");
oLi.appendChild(textNode);
oUl.insertBefore(oLi,oUl.firstElementChild);
}
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JS</li>
</ul>
<input type="text" id="txt"><input type="button" id="btn" value="插入">
</body>
</html>
删除元素
A.removeChild(B);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick=function(){
var oUl = document.getElementById("list");
oUl.removeChild(oUl.lastElementChild);
}
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JS</li>
</ul>
<input type="button" value="删除" id="btn">
</body>
</html>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick=function(){
var oUl = document.getElementById("list");
document.body.removeChild(oUl);
}
}
</script>
复制元素
obj.cloneNode(bool)
参数 obj 表示被复制的元素,而参数 bool 是一个布尔值,取值如下。1 或 true:表示复制元素本身以及复制该元素下的所有子元素。0 或 false:表示仅仅复制元素本身,不复制该元素下的子元素。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick=function(){
var oUl = document.getElementById("list");
document.body.appendChild(oUl.cloneNode(1));
}
}
</script>
</head>
<body>
<ul id="list">
<li>HTML</li>
<li>CSS</li>
<li>JS</li>
</ul>
<input type="button" value="删除" id="btn">
</body>
</html>
替换元素
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function () {
var oBtn = document.getElementById("btn");
oBtn.onclick=function(){
//获取 body 第一个元素
var oFirst = document.querySelector("body *:first-child");
//获取2个文本框
var oTag = document.getElementById("tag");
var oTxt = document.getElementById("txt");
//利用拿到的标签和数据创建一个新的元素
var oNewTag = document.createElement(oTag.value);
var oNewTxt = document.createTextNode(oTxt.value);
oNewTag.appendChild(oNewTxt);
//元素替换
document.body.replaceChild(oNewTag,oFirst);
}
}
</script>
</head>
<body>
<p>JS</p>
<hr>
输入标签: <input type="text" id="tag"><br>
输入内容: <input type="text" id="txt"><br>
<input type="button" id="btn" value="替换">
</body>
</html>