一、简介
DOM:是Document Object Model( 文档对象模型 )的缩写。
DOM是把html里面的各种数据当作对象进行操作的一种思路。
比如一个超链,作为一个DOM对象,就可以使其隐藏,修改其href指向的地址。
二、设计使用:
节点:DOM把所有的html都转换为节点
整个文档document,元素(id),元素属性(attributes[]),元素内容(childNodes[]),注释
获取节点:
通过id获取元素节点: var div1 = document.getElementById("d1");
通过标签名称获取元素节点:
var divs = document.getElementsByTagName("div");
for(i=0;i<
divs.length
;i++){
document.write(divs[i]);
document.write("<br>");
}
通过类名获取元素节点: var elements= document.getElementsByClassName("d");
通过表单元素的name获取元素节点: var elements= document.getElementsByName("userName");
获取不到的原因: javascript是解释语言,是顺序执行的。执行方法时,若该元素尚未加载,则无法取到。
获取属性节点:
首先通过getElementById获取元素节点,然后通过元素节点的attributes获取其下所有的属性节点。
因为属性节点是多个,所以是以数组的形式返回出来的,接着通过for循环遍历,查看每个节点的nodeName和nodeValue
(nodeName和nodeValue表示一个节点的名称和值)
如果要获取一个指定属性的值,可以采用如下风格,as表示所有的属性,as["id"]取出名称是id的属性
as["id"].nodeValue
<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>
获取内容节点:
首先通过document.getElementById获取元素节点,然后通过childNodes获取其所有的子节点。 其中第一个子节点,就是其内容节点。
然后借助nodeName和nodeValue把内容节点的名称和值打印出来。
注: nodeName和nodeValue表示一个节点的名称和值
<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>
节点的属性:
节点名称:nodeName表示一个节点的名字
document.nodeName 文档的节点名,是 固定的#document
div1.nodeName 元素的节点名,是对应的标签名 div
div1.attributes[0].nodeName 属性的节点名,是对应的属性名 id
div1.childNodes[0].nodeName 内容的节点名,是固定的 #text
节点值:nodeValue表示一个节点的值
document.nodeValue 文档的节点值,是 null
div1.nodeValue 元素的节点值,是null
div1.attributes[0].nodeValue 属性的节点值,是对应的属性值 d1
div1.childNodes[0].nodeValue 内容的节点值,是内容 即: #text
节点类型:nodeType表示一个节点的类型
不同的节点类型,对应的节点类型值是不一样的
document.nodeType 文档的节点类型,是 9 注释是8
div1.nodeType 元素的节点类型,是 1
div1.attributes[0].nodeType 属性的节点类型,是 2
div1.childNodes[0].nodeType 内容的节点类型,是 3
元素的文本内容:修改与获取内容的值可以通过 childNodes[0].nodeValue进行
还有个简便办法就是通过innerHTML进行。 效果是一样的。
function changeDiv1(){
document.getElementById("d1").childNodes[0].nodeValue= "通过childNode[0].value改变内容";
}
function changeDiv2(){
document.getElementById("d1").innerHTML= "通过innerHTML改变内容";
}
元素上的属性:元素上的属性,比如id,value 可以通过 . 直接访问
如果是自定义属性,那么可以通过如下两种方式来获取
getAttribute("test")
attributes["test"].nodeValue
注: class需要通过className获取
<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
通过给元素的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>
改变背景色:通过给元素的style.backgroundColor 赋值,修改样式
<div id="d1" style="background-color:pink">Hello HTML DOM</div>
<button οnclick="change()">改变div的背景色</button>
<script>
function change(){
var d1 = document.getElementById("d1");
d1.style.backgroundColor="green";
}
</script>
事件:
焦点事件: <
input
type
=
"text"
onfocus
=
"f()"
onblur
=
"b()"
id
=
"input1"
placeHolder
=
"输入框1"
>
当组件获取焦点的时候,会触发onfocus事件
当组件失去焦点的时候,会触发onblur事件
鼠标事件:
当在组件上鼠标按下的时候,会触发onmousedown事件
当在组件上鼠标弹起的时候,会触发onmouseup事件
当在组件上鼠标经过的时候,会触发onmousemove事件
当在组件上鼠标进入的时候,会触发onmouseover事件
当在组件上鼠标退出的时候,会触发onmouseout事件
注: 当鼠标进入一个组件的时候,onmousemove和onmouseover都会被触发,区别在于无论鼠标在组件上如何移动,onmouseover只会触发一次,onmousemove每次移动都会触发
键盘事件: <
input
type
=
"button"
onkeydown
=
"down(event)"
value
=
"用于演示按下keydown"
>
当在组件上键盘按下的时候,会触发onkeydown事件
当在组件上键盘按下的时候,也会触发onkeypress事件
当在组件上键盘弹起的时候,会触发onkeyup事件
点击事件: <
input
type
=
"button"
onclick
=
"singleClick()"
ondblclick
=
"doubleClick()"
value
=
"用于演示单击和双击"
>
当在组件上单击的时候,会触发onclick事件
当在组件上双击的时候,会触发ondblclick事件
注1:在组件上,按下空格或则回车键也可以造成单击的效果,但是却不能造成双击的效果
注2: 自定义函数不要使用click(),这是保留函数名。
变化事件:
当组件的值发生变化的时候,会触发onchange事件
注:对于输入框而言,只有在失去焦点的时候,才会触发onchange,
<input type="text" id="t1" οnchange="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>
提交事件:可以在form元素上,监听提交事件
当form元素@提交的时候,会触发onsubmit事件
<form action="/study/login.jsp" οnsubmit="login()">
账号:<input type="text" name="name"> <br/>
密码:<input type="password" name="password" > <br/>
<input type="submit" value="登录">
</form>
<script>
function login(){
alert("提交表单");
}
</script>
加载事件:
当整个文档加载成功,或者一个图片加载成功,会触发加载事件
当body元素或者img@加载的时候,会触发onload事件
<script>
function loadBody(){
document.getElementById("message1").innerHTML="文档加载成功";
}
function loadImg(){
document.getElementById("message2").innerHTML="图片加载成功";
}
</script>
<body οnlοad="loadBody()">
<div id="message1"></div>
<div id="message2"></div>
</body>
<img οnlοad="loadImg()" src="a.gif"/>
当前事件:this表示触发事件的组件,可以在调用函数的时候,作为参数传进去
<input type="button" οnclick="singleClick(this)" value="演示this的按钮1" >
<input type="button" οnclick="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>
阻止事件的发生:比如在提交一个表单的时候,如果用户名为空,弹出提示,并阻止原本的提交
1. 在调用函数的时候,增加一个return
2. 在函数中,如果发现用户名为空,则返回false
3. 当onSubmit得到的返回值是false的时候,表单的提交功能就被取消了
<form method="post" action="/study/login.jsp" οnsubmit="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>
节点关系:
通过parentNode获取父节点。
分别通过 previousSibling和nextSibling属性获取前一个,以及后一个同胞节点。
标签之间有任何字符、空白、换行都会产生文本元素。 所以获取到的节点是#text.
子节点关系有:
firstChild 第一个子节点
lastChild 最后一个子节点
childNodes 所有子节点
firstChild 如果父节点的开始标签和第一个元素的开始标签之间有文本、空格、换行,那么firstChild第一个子节点将会是文本节点,不会是第一个元素节点
childNodes和children都可以获取一个元素节点的子节点。
childNodes 会包含文本节点
children 会排除文本节点
创建元素节点:通过createElement 创建一个新的元素节点
接着把该元素节点,通过appendChild加入到另一个元素节点div1中
function add(){
var hr=document.createElement("hr");
var div1 = document.getElementById("d");
div1.appendChild(hr);
}
创建文本节点:
首先创建一个元素节点p (p是p标签,不是随便命名的变量名)
接着通过createTextNode创建一个内容节点text
把text加入到p
再把p加入到div
function add(){
var p=document.createElement("p");
var text = document.createTextNode("这是通过DOM创建出来的<
p
>");
p.appendChild(text);
var div1 = document.getElementById("d");
div1.appendChild(p);
}
创建属性节点:
首先创建一个元素节点a
接着创建一个内容节点content
把content加入到a
然后通过createAttribute创建一个属性节点 href
设置href的值为http:12306.com
通过setAttributeNode把该属性设置到元素节点a上
最后把a加入到div
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);
}
删除元素节点:
第一:先获取该元素的父节点
第二:通过父节点,调用removeChild 删除该节点
function removeDiv(){
var parentDiv = document.getElementById("parentDiv");
var div2= document.getElementById("div2");
parentDiv.removeChild(div2);
}
删除属性节点:
var link= document.getElementById("link");
link.removeAttribute("href");
第一:先获取该元素节点
第二:元素节点,调用removeAttribute删除指定属性节点
删除文本节点:
1. 通过childNodes[0] 获取文本节点
注:children()[0] 只能获取第一个子元素节点,不能获取文本节点
2. 通过removeChild删除该文本节点
但是这种方式比较麻烦,一般都是直接通过innerHTML设置为空即可。
注: 通过innerHTML=""的方式,同样会导致文本子节点被删除。
function removeDiv1(){
var parentDiv = document.getElementById("parentDiv");
var textNode = parentDiv.childNodes[0];
parentDiv.removeChild(textNode);
}
function removeDiv2(){
var parentDiv = document.getElementById("parentDiv");
parentDiv.innerHTML="";
}
function recover(){
var parentDiv = document.getElementById("parentDiv");
parentDiv.innerHTML="这里是文本 ";
}
替换节点:也需要先获取父节点,然后通过父节点替换子节点
1. 获取父节点
2. 创建子节点
3. 获取被替换子节点
4. 通过replaceChild进行替换
注: replaceChild 第一个参数是保留的节点,第二个参数是被替换的节点
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);
}
在后面追加节点:通过appendChild追加节点。 追加节点一定是把新的节点插在最后面
1. 创建新节点
2. 获取父节点
3. 通过appendChild追加
function appendDiv(){
var d4= document.createElement("div");
var text = document.createTextNode("第四个div");
d4.appendChild(text);
var parentDiv = document.getElementById("parentDiv");
parentDiv.appendChild(d4);
}
在前方插入节点:有时候,需要在指定位置插入节点,而不是只是追加在后面。
这个时候就需要用到insertBefore
1. 创建新节点
2. 获取父节点
3. 获取需要加入的子节点
4. 通过insertBefore插入
注: insertBefore的第一个参数是新元素,第二个参数是插入位置
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);
}
动态加载JS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script id="s">
function p(){
var script=document.createElement("script")//创建元素节点
script.src="../JavaScript/test.js"//相对路径地址
var s=document.getElementById("s")//获取第一个script
s.parentNode.insertBefore(script,s)//在第一个script前插入
}
</script>
</head>
<body>
<button onclick="p()">动态加载js</button>
</body>
</html>
常用场景:
删除行为前的提示,验证账号密码是否为空,验证长度
验证年龄是否为数字,验证年龄是否为整数,验证Email格式是否正确
隐藏和显示
表格排序
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
table{
border-collapse:collapse;
width:90%;
}
tr{
border-bottom-style: solid;
border-bottom-width: 1px;
border-bottom-color: lightgray;
height:35px;
}
td{
width:25%;
text-align:center;
}
a{
text-decoration: none;
color:skyblue;
}
</style>
<script>
var col = 0;
var reverse = false;
function sort(column){
if(column == col)
reverse = !reverse;
col = column;
var tbody = document.getElementById("tbody");
//通过getElementsByTagName取出来是一个Collection
var trsCollection = document.getElementsByTagName("tr");
//因为Collection没有自带的排序函数,所以需要转换为数组,利用数组自带的排序
var trs =new Array();
for (var i=1; i <trsCollection.length; i++) {
trs.push(trsCollection[i]);
}
trs.sort(comparator);
for (var i=0; i <trs.length; i++) {
tbody.appendChild(trs[i]);
}
}
function comparator(tr1,tr2){
var td1 = tr1.children[col].innerHTML; //取某一行的第col列中的内容
var td2 = tr2.children[col].innerHTML;
if(reverse)
return td1.localeCompare(td2);
else
return td2.localeCompare(td1);
}
</script>
<table>
<tbody id="tbody">
<tr >
<td ><a href="javascript:void(0)" onclick="sort(0)">id</a></td>
<td ><a href="javascript:void(0)" onclick="sort(1)">名称</a></td>
<td ><a href="javascript:void(0)" onclick="sort(2)">血量</a></td>
<td ><a href="javascript:void(0)" onclick="sort(3)">伤害</a></td>
</tr>
<tr >
<td>1</td>
<td>gareen</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>deadbrother</td>
<td>400</td>
<td>90</td>
</tr>
</tbody>
</table>
</head>
<body>
</body>
</html>