DOM:文档对象模型
把html里面的各种数据当做对象进行操作的一种思路
一、节点概念
DOM把所有的html都转换为节点,整个文档、元素、元素属性、元素内容、注释,都是节点
本例通过document.getElementById获取了id=d1的div标签对应的元素节点
然后通过attributes 获取了该节点对应的属性节点
接着通过childNodes获取了内容节点
<html>
<body>
<div id="d1">hello HTML DOM</div>
</body>
<script>
function p(s){
document.write(s);
document.write("<br>");
}
var div1 = document.getElementById("d1");
p("文档节点"+document);
p("元素"+div1);
p("属性节点"+div1.attributes[0]);
p("内容节点"+div1.childNodes[0]);
</script>
</html>
二、获取节点
1.通过id获取元素节点
var div1=document.getElementById(“d1”);
2.通过标签名获取一个元素数组 var divs=document.getElementsByTagName("div");
3.通过类名获取节点数组 var elements=document.getElementsByClassName("d");
4.通过表单元素的name获取元素节点 var elements=document.getElementsByName("name");
<html>
用户名 <input name="userName"> <br>
密码 <input name="userPassword">
<br>
<script>
var elements= document.getElementsByName("userName");
for(i=0;i<elements.length;i++){
document.write(elements[i]);
document.write("<br>");
}
</script>
</html>
5.获取属性节点:首先通过getElementById获取元素节点,然后通过元素节点的attributes以数组形式获取其下的所有属性节点
<html>
<div id="d1" align="center" class="abc">hello HTML DOM</div>
<script>
var div1 = document.getElementById("d1");
var as = div1.attributes;
document.write("div总共有"+as.length +" 个属性");
document.write("分别是:");
for(i = 0; i< as.length; i++){
document.write("<br>");
document.write(as[i].nodeName);
document.write(":");
document.write(as[i].nodeValue);
}
document.write("<br>");
document.write("div的id属性值是:"+ as["id"].nodeValue);
</script>
</html>
6.获取内容节点:首先通过document.getElementById获取元素节点,然后通过childNodes获取其所有的子节点,其中第一个子节点就是其内容节点
<html>
<div id="d1" align="center" class="abc">hello HTML DOM</div>
<script>
var div1 = document.getElementById("d1");
var content = div1.childNodes[0];
document.write("div的内容节点名是:"+content.nodeName);
document.write("<br>");
document.write("div的内容节点值是:"+content.nodeValue);
</script>
</html>
三、节点的属性
1.节点名称nodeName
<html>
<div id="d1">hello HTML DOM</div>
<script>
function p(s){
document.write(s);
document.write("<br>");
}
var div1 = document.getElementById("d1");
p("document的节点名称:"+document.nodeName);
p("div元素节点的节点名称:"+div1.nodeName);
p("div下属性节点的节点名称:"+div1.attributes[0].nodeName);
p("div下内容节点的节点名称:"+div1.childNodes[0].nodeName);
</script>
</html>
2.节点值nodeValue
<html>
<div id="d1">hello HTML DOM</div>
<script>
function p(s){
document.write(s);
document.write("<br>");
}
var div1 = document.getElementById("d1");
p("document是没有nodeValue的:"+document.nodeValue);
p("元素节点是没有nodeValue的:"+div1.nodeValue);
p("属性节点id的nodeValue:"+div1.attributes[0].nodeValue);
p("内容节点的nodeValue:"+div1.childNodes[0].nodeValue);
</script>
</html>
3.节点类型nodeType
4.修改与获取元素的文本内容
①通过x.childNodes[0].nodeValue;
②通过x.innerHTML
<html>
<div id="d1">hello HTML DOM</div>
<script>
function changeDiv1(){
document.getElementById("d1").childNodes[0].nodeValue= "通过childNode[0].value改变内容";
}
function changeDiv2(){
document.getElementById("d1").innerHTML= "通过innerHTML改变内容";
}
</script>
<button onclick="changeDiv1()">通过内容节点方式改变div的内容</button>
<button onclick="changeDiv2()">通过innerHTML改变div的内容</button>
</html>
5.元素上的属性
id,value等可以直接通过x.id,x.value等直接访问
自定义属性可以通过x.getAttribute(“a”);或x.attributes[“a”].nodeValue;来获取
<html>
<div id="d1">hello HTML DOM</div>
<script>
function get(){
var input1 = document.getElementById("input1");
var s = "id="+input1.id + "<br>";
s += "value="+input1.value + "<br>";
s += "class="+input1.className + "<br>";
s += "test="+input1.getAttribute("test")+ "<br>";
s += "test="+input1.attributes["test"].nodeValue+ "<br>";
document.getElementById("d1").innerHTML= s;
}
</script>
<input id="input1" class="class1 class2" test="t1" value="这是一个输入框">
<br>
<button onclick="get()">获取input的属性</button>
<div style="height:30px"></div>
</html>
四、节点样式
一个元素节点的style属性即对应的css
1.隐藏和显示:通过给元素的style.display赋值改变显示还是隐藏
<button onclick="hide()">隐藏div</button>
<button onclick="show()">显示div</button>
<br>
<br>
<div id="d">
这是一个div
</div>
<script>
function hide(){
var d = document.getElementById("d");
d.style.display="none";
}
function show(){
var d = document.getElementById("d");
d.style.display="block";
}
</script>
2.改变背景色:通过给元素的style.backgroundColor赋值,修改背景色
<div id="d1" style="background-color:pink">Hello HTML DOM</div>
<button onclick="change()">改变div的背景色</button>
<script>
function change(){
var d1 = document.getElementById("d1");
d1.style.backgroundColor="green";
}
</script>
五、事件
1.焦点事件:获取焦点onfocus和失去焦点onblur
<input type="text" onfocus="f()" onblur="b()" id="input1" placeHolder="输入框1" >
<br>
<br>
<input type="text" id="input2" placeHolder="输入框2">
<br>
<br>
<div id="message"></div>
<script>
function f(){
document.getElementById("message").innerHTML="输入框1获取了焦点";
}
function b(){
document.getElementById("message").innerHTML="输入框1丢失了焦点";
}
</script>
2.鼠标事件:在组件上有鼠标按下onmousedown,鼠标弹起onmouseup,鼠标经过onmousemove,鼠标进入onmouseover,鼠标退出onmouseout
当鼠标进入一个组件时,onmousemove和onmouseover都会触发,但鼠标在组件上每次移动时都只会触发onmousemove
<input type="button" onmousedown="down()" onmouseup="up()" value="用于演示按下和弹起" >
<br>
<br>
<input type="button" onmousemove="move()" value="用于演示鼠标经过" >
<br>
<br>
<input type="button" onmouseover="over()" value="用于演示鼠标进入" >
<br>
<br>
<input type="button" onmouseout="out()" value="用于演示鼠标退出" >
<br>
<br>
<div id="message"></div>
<script>
var number = 0;
function down(){
document.getElementById("message").innerHTML="按下了鼠标";
}
function up(){
document.getElementById("message").innerHTML="弹起了鼠标";
}
function move(){
document.getElementById("message").innerHTML="鼠标经过次数:"+(++number);
}
function over(){
document.getElementById("message").innerHTML="鼠标进入次数:"+(++number);
}
function out(){
document.getElementById("message").innerHTML="鼠标退出";
number = 0;
}
</script>
3.键盘事件:
在组件上(先用鼠标选中组件)键盘按下onkeydown/onkeypress,键盘弹起onkeyup
“记得要先用鼠标选中该组件,然后敲击键盘”
<br>
<input type="button" onkeydown="down(event)" value="用于演示按下keydown" >
<br>
<br>
<input type="button" onkeypress="press(event)" value="用于演示按下keypress" >
<br>
<br>
<input type="button" onkeyup="up()" value="用于演示弹起" >
<br>
<br>
<div id="message">
</div>
<script>
var number =0;
function down(e){
var text = "按下了键" + e.keyCode;
if(e.shiftKey==1)
text += " 并且按下了shift键";
document.getElementById("message").innerHTML=text ;
}
function up(){
document.getElementById("message").innerHTML="弹起了键盘";
}
function press(e){
var text = "按下了键" + e.keyCode;
if(e.shiftKey==1)
text += " 并且按下了shift键";
document.getElementById("message").innerHTML=text ;
}
</script>
4.点击事件:在组件上单机onclick,双击ondblclick
空格或回车也可以造成单机的效果
<input type="button" onclick="singleClick()" ondblclick="doubleClick()" value="用于演示单击和双击" >
<br>
<br>
<div id="message"></div>
<script>
function singleClick(){
document.getElementById("message").innerHTML="单击按钮";
}
function doubleClick(){
document.getElementById("message").innerHTML="双击按钮";
}
</script>
5.变化事件:当组件的值发生变化时,会触发onchange事件
对于输入框而言,只有在失去焦点的时候才会触发onchange
<input type="text" id="t1" onchange="change()" value="" >
<br>
<br>
<input type="button" value="令输入框失去焦点的按钮" >
<br>
<br>
<div id="message"></div>
<script>
function change(){
var message = document.getElementById("message");
var t1 = document.getElementById("t1");
message.innerHTML = "输入框的值变为了: "+ t1.value;
}
</script>
6.提交事件:可以在form元素上,监听提交事件,当form元素@提交的时候,会触发onsubmit事件
<form action="/study/login.jsp" onsubmit="login()">
账号:<input type="text" name="name"> <br/>
密码:<input type="password" name="password" > <br/>
<input type="submit" value="登录">
</form>
<script>
function login(){
alert("提交表单");
}
</script>
7.加载事件:当整个文档或一个图片加载成功,会触发加载时间;即当body元素或img@加载的时候,会触发onload事件
<script>
function loadBody(){
document.getElementById("message1").innerHTML="文档加载成功";
}
function loadImg(){
document.getElementById("message2").innerHTML="图片加载成功";
}
</script>
<body onload="loadBody()">
<div id="message1"></div>
<div id="message2"></div>
</body>
<img onload="loadImg()" src="https://how2j.cn/example.gif"/>
8.当前组件:this表示触发事件的组件,可以在调用函数的时候作为参数传进去
<input type="button" onclick="singleClick(this)" value="演示this的按钮1" >
<input type="button" onclick="singleClick(this)" value="演示this的按钮2" >
<br>
<br>
<div id="message"></div>
<script>
function singleClick(button){
var s = "被点击的按钮上的文本是: "+button.value;
document.getElementById("message").innerHTML=s;
}
</script>
9.阻止事件的发生:比如在提交一个表单的时候,如果用户名为空,则弹出提示并阻止原本的提交
在调用函数的时候增加一个return;在函数中如果发现用户名为空则返回false;当onsubmit得到的返回值是false时,表单的提交就被取消了
<form method="post" action="/study/login.jsp" onsubmit="return login()">
账号:<input id="name" type="text" name="name"> <br/>
密码:<input type="password" name="password" > <br/>
<input type="submit" value="登录">
</form>
<script>
function login(){
var name = document.getElementById("name");
if(name.value.length==0){
alert("用户名不能为空");
return false;
}
return true;
}
</script>
六、节点关系
1.节点关系有parentNode, firstNode, lastNode, previousSibling, nextSibling, childNodes, children
2.父节点关系:通过parentNode获取父节点
本例中从id="d1"的div开始递归获取其父节点,分别获取到如下:
div[id="parentDiv]->body->html->document
<html>
<body>
<script>
var node = null;
function showParent(){
if(null==node)
node = document.getElementById("d1");
if(document == node)
alert("已是根节点:document");
else{
alert(node.parentNode);
node = node.parentNode;
}
}
</script>
<div id="parentDiv">
父Div的内容
<div id="d1">第一个div</div>
<div id="d2">第二个div</div>
<div id="d3">第三个div</div></div>
<button onclick="showParent()">不断递归d1的父节点</button>
</body>
</html>
3.同胞节点关系:分别通过previousSibling和nextSibling属性获取前一个以及后一个同胞节点
本例中,因为d1和d2标签是紧挨着的,所以d2的前一个节点是d1;
而d2和d3不是紧挨着的, 标签之间有任何字符、空白、换行都会产生文本元素#text
<script>
function showPre(){
var d2 = document.getElementById("d2");
alert(d2.previousSibling.innerHTML);
}
function showNext(){
var d2 = document.getElementById("d2");
alert(d2.nextSibling.nodeName);
}
</script>
<div id="parentDiv">
父Div的内容
<div id="d1">第一个div</div><div id="d2">第二个div</div>
<div id="d3">第三个div</div>
</div>
<button onclick="showPre()">获取d2的前一个同胞</button>
<button onclick="showNext()">获取d2的后一个同胞</button>
4.子节点关系:firstChild第一个子节点,lastChild最后一个子节点,childNodes所有子节点(数组)
注:firstChild 如果父节点的开始标签和第一个元素的开始标签之间有文本、空格、换行,那么firstChild第一个子节点将会是文本节点,不会是第一个元素节点;
lastChild 和firstChild同理。 在本例中故意让第3个元素的结束标签与div的结束标签紧挨着,所以最后一个子节点就是第三个标签;
子元素个数一共是6个。
<script>
function showfirst(){
var div = document.getElementById("parentDiv");
alert(div.firstChild.nodeName);
}
function showlast(){
var div = document.getElementById("parentDiv");
alert(div.lastChild.nodeName);
}
function showall(){
var div = document.getElementById("parentDiv");
alert(div.childNodes.length);
}
</script>
<div id="parentDiv">
父Div的内容
<div id="d1">第一个div</div>
<div id="d2">第二个div</div>
<div id="d3">第三个div</div></div>
<button onclick="showfirst()">第一个子节点</button>
<button onclick="showlast()">最后一个子节点</button>
<button onclick="showall()">所有子节点数量</button>
5.children属性会排除文本节点,所以将4中的childNodes.length换为children.length则结果为3
七、创建节点
1.创建元素节点:c=document.createElement("…");
插入元素节点:p.appendChild©;
<html>
<div id="d">Hello HTML DOM</div>
<script>
function add(){
var hr=document.createElement("hr");
var div1 = document.getElementById("d");
div1.appendChild(hr);
}
</script>
<button onclick="add()">在div中追加一个hr元素</button>
</html>
2.创建文本节点:首先创建一个元素节点p,然后通过createTextNode创建一个内容节点text,然后把text加入到p,再把p加入到div
<html>
<div id="d">Hello HTML DOM</div>
<script>
function add(){
var p=document.createElement("p");
var text = document.createTextNode("这是通过DOM创建出来的<p>");
p.appendChild(text);
var div1 = document.getElementById("d");
div1.appendChild(p);
}
</script>
<button onclick="add()">在div中追加一个p元素</button>
</html>
3.创建属性节点:首先创建一个元素节点a,接着创建一个内容(文本)节点content,把content加入到a中;然后通过createAttribute创建一个属性节点,设置属性节点的nodeValue后,通过setAttributeNode把该属性设置到元素节点a上,最后把a加入到div中
<html>
<div id="d">Hello HTML DOM<br></div>
<script>
function add(){
var a=document.createElement("a");
var content = document.createTextNode("http://12306.com");
a.appendChild(content);
var href = document.createAttribute("href");
href.nodeValue="http://12306.com";
a.setAttributeNode(href);
var div1 = document.getElementById("d");
div1.appendChild(a);
}
</script>
<button onclick="add()">在div中追加一个超链</button>
</html>
八、删除节点
1.删除元素节点:两个步骤
①先获取该元素的父节点
②通过父节点,调用removeChild删除该节点
<script>
function removeDiv(){
var parentDiv = document.getElementById("parentDiv");
var div2= document.getElementById("div2");
parentDiv.removeChild(div2);
}
</script>
<div id="parentDiv">
<div id="div1">安全的div</div>
<div id="div2">即将被删除的div</div>
</div>
<button onclick="removeDiv()">删除第二个div</button>
2.删除属性节点:两个步骤
①先获取该元素节点
②调用元素节点的removeAttribute删除指定属性节点
<script>
function removeHref(){
var link= document.getElementById("link");
link.removeAttribute("href");
}
</script>
<a id="link" href="http://12306.com">http://12306.com</a>
<br>
<button onclick="removeHref()">删除超链的href属性</button>
3.删除文本节点:设置innerHTML="";
九、替换节点
①获取父节点
②创建子节点
③获取将被替换的子节点
④通过父节点的replaceChild(新节点,将被替换节点);替换
<div id="parentDiv">
<div id="d1">第一个div</div>
<div id="d2">第二个div</div>
<div id="d3">第三个div</div>
</div>
<script>
function replaceDiv(){
var d4= document.createElement("div");
var text = document.createTextNode("第四个div");
d4.appendChild(text);
var d3 = document.getElementById("d3");
var parentDiv = document.getElementById("parentDiv");
parentDiv.replaceChild(d4,d3);
}
</script>
<button onclick="replaceDiv()">替换第3个div</button>
十、插入节点
1.在最后面追加新节点:
①创建新节点
②获取父节点
③通过appendChild追加新节点
<div id="parentDiv">
<div id="d1">第一个div</div>
<div id="d2">第二个div</div>
<div id="d3">第三个div</div>
</div>
<script>
function appendDiv(){
var d4= document.createElement("div");
var text = document.createTextNode("第四个div");
d4.appendChild(text);
var parentDiv = document.getElementById("parentDiv");
parentDiv.appendChild(d4);
}
</script>
<button onclick="appendDiv()">追加第4个div</button>
2.在指定位置插入节点
①创建新节点
②获取父节点
③获取插入位置的子节点
④通过父节点的insertBefore(①,③)插入到③中节点之前
全过程涉及了父、子、子三个节点
<div id="parentDiv">
<div id="d1">第一个div</div>
<div id="d2">第二个div</div>
<div id="d3">第三个div</div>
</div>
<script>
function insertDiv(){
var d25= document.createElement("div");
var text = document.createTextNode("第二点五个div");
d25.appendChild(text);
var parentDiv = document.getElementById("parentDiv");
var d3 = document.getElementById("d3");
parentDiv.insertBefore(d25,d3);
}
</script>
<button onclick="insertDiv()">在第二和第三之间,插入第二点五个div</button>
十一、例题:表格排序
<style type="text/css">
table {
width: 600px;
text-align: center;
border-collapse: collapse;
}
td {
border-bottom: solid 1px gray;
width: 25%;
padding: 10px;
}
a {
text-decoration: none;
color: #0000FF;
}
</style>
<table>
<tr>
<td><a href="#nowhere" onclick="sort1(0)">id</a></td>
<td><a href="#nowhere" onclick="sort1(1)">名称</a></td>
<td><a href="#nowhere" onclick="sort1(2)">血量</a></td>
<td><a href="#nowhere" onclick="sort1(3)">伤害</a></td>
</tr>
<tr>
<td>1</td>
<td>garee</td>
<td>340</td>
<td>58</td>
</tr>
<tr>
<td>2</td>
<td>teemo</td>
<td>320</td>
<td>76</td>
</tr>
<tr>
<td>3</td>
<td>annie</td>
<td>380</td>
<td>38</td>
</tr>
<tr>
<td>4</td>
<td>deadbrothe</td>
<td>400</td>
<td>90</td>
</tr>
</table>
<script type="text/javascript">
var sum = 0; //单数小到大排序,双数大到小排序
function sort1(t) {
var a = document.getElementsByTagName("td");
var b = a[4 + t].parentNode; //b是<tr>
var c = b.parentNode; //c是<table>
sum++;
for (i = 4 + t; i < 16 + t; i = i + 4) {
for (j = i + 4; j <= 16 + t; j = j + 4) {
if (sum % 2 == 0) {
if (a[i].innerHTML > a[j].innerHTML) {
c.insertBefore(a[j].parentNode, a[i].parentNode);
}
}
else {
if (a[i].innerHTML < a[j].innerHTML) {
c.insertBefore(a[j].parentNode, a[i].parentNode);
}
}
}
}
}
</script>