文章目录
一、什么是DOM
• DOM,全称Document Object Model文档对象模型。
• JS中通过DOM来对HTML文档进行操作。只要理解了DOM就可以随
心所欲的操作WEB页面。
• 文档
– 文档表示的就是整个的HTML网页文档
• 对象
– 对象表示将网页中的每一个部分都转换为了一个对象。
• 模型
– 使用模型来表示对象之间的关系,这样方便我们获取对象。
二、模型
三、节点
• 节点Node,是构成我们网页的最基本的组成部分,网页中的每一个部分都可以称为是一个节点。
• 比如:html标签、属性、文本、注释、整个文档等都是一个节点。
• 虽然都是节点,但是实际上他们的具体类型是不同的。
• 节点的类型不同,属性和方法也都不尽相同
• 节点:Node——构成HTML文档最基本的单元。
• 常用节点分为四类:
a. 文档节点:整个HTML文档
• 文档节点document,代表的是整个HTML文档,网页中的所有节点都是它的子节点。
• document对象作为window对象的属性存在的,我们不用获取可以直接使用。
• 通过该对象我们可以在整个文档访问内查找节点对象,并可以通过该对象创建各种节点对象。
b. 元素节点:HTML文档中的HTML标签
• HTML中的各种标签都是元素节点,这也是我们最常用的一个节点。
• 浏览器会将页面中所有的标签都转换为一个元素节点,我们可以通过document的方法来获取元素节点。
• 比如:
– document.getElementById()
– 根据id属性值获取一个元素节点对象。
c. 文本节点:HTML标签中的文本内容
• 文本节点表示的是HTML标签以外的文本内容,任意非HTML的文本都是文本节点。
• 它包括可以字面解释的纯文本内容。
• 文本节点一般是作为元素节点的子节点存在的。
• 获取文本节点时,一般先要获取元素节点。在通过元素节点获取文本节点。
• 例如:
– 元素节点.firstChild;
– 获取元素节点的第一个子节点,一般为文本节点
d. 属性节点:元素的属性
• 属性节点表示的是标签中的一个一个的属性,这里要注意的是属性节点并非是元素节点的子节点,而是元素节点的一部分。
• 可以通过元素节点来获取指定的属性节点。
• 例如:
– 元素节点.getAttributeNode(“属性名”);
• 注意:我们一般不使用属性节点。
四、获取元素节点
• 通过document对象调用
1. getElementById()
– 通过id属性获取一个元素节点对象
代码片段:
<body>
<p id="hh">你猜我是谁。。。</p>
<button οnclick="myFunction()">click</button>
<p id="demo"></p>
<script type="text/javascript">
var x=document.getElementById("hh");
function myFunction(){
document.getElementById("demo").innerHTML=x.innerHTML;
}
</script>
</body>
运行结果:
2. getElementsByTagName()
– 通过标签名获取一组元素节点对象
代码片段:
<body>
<p>你是不是傻!!!</p>
<div id="main" style="color: #DF5000;">
<p>???????</p>
<p>!!!!!!!</p>
</div>
<p id="demo1"></p>
<p id="demo2"></p>
<script type="text/javascript">
var y=document.getElementsByTagName("p");
var a=document.getElementById("main").getElementsByTagName("p");
document.getElementById("demo1").innerHTML="第一个p标签文本是:"+y[0].innerHTML;
document.getElementById("demo2").innerHTML="main中的第一个p标签的文本是:"+a[0].innerHTML;
</script>
</body>
运行结果:
3. getElementsByClassName()
– 通过class属性获取一组元素节点对象
部分片段:
<body>
<div class="hhh" style="color: #008B8B;">
<p class="hhh">&&&&&&&&</p>
<p class="hhh">DomDom</p>
</div>
<p id="demo3"></p>
<script type="text/javascript">
var b=document.getElementsByClassName("hhh");
document.getElementById("demo3").innerHTML="hhh中的第一个p标签文本是:"+b[1].innerHTML;
</script>
</body>
运行结果:
五、获取元素节点的子节点
• 通过具体的元素节点调用
1. getElementsByTagName()
– 方法,返回当前节点的指定标签名后代节点
代码如上
2. childNodes
- 属性,表示当前节点的所有子节点
- 根据DOM标签标签间空白也会当成文本节点
- 注意:在IE8及以下的浏览器中,不会将空白文本当成子节点
- 所以该属性在IE8中会返回4个子元素而其他浏览器是9个
部分代码:
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<button id="btn">查找#city下所有li节点</button>
<script>
window.onload = function(){//等到页面加载结束,再显示
btn.οnclick=function(){
var city = document.getElementById("city");
//返回#city的所有子节点
var cns = city.childNodes;
alert(cns.length);
for(var i=0 ; i<cns.length ; i++){
alert(cns[i].innerHTML);
}
}
}
</script>
<body>
运行结果:
<!-- children属性可以获取当前元素的所有子元素,不包括空格-->
var cns2 = city.children;
alert(cns2.length);
3. firstChild
– 属性,表示当前节点的第一个子节点
-
firstChild可以获取到当前元素的第一个子节点(包括空白文本节点)
-
firstElementChild获取当前元素的第一个子元素
部分代码:
<script>
btn.onclick = function(){
//获取id为phone的元素
var phone = document.getElementById("phone");
//返回#phone的第一个子节点
//phone.childNodes[0];
var fir = phone.firstChild;
/*
* firstElementChild不支持IE8及以下的浏览器,
* 如果需要兼容他们尽量不要使用
*/
fir = phone.firstElementChild;
alert(fir);
};
</script>
4. lastChild
– 属性,表示当前节点的最后一个子节点
-
lastChild可以获取到当前元素的第一个子节点(包括空白文本节点)
-
lastElementChild获取当前元素的第一个子元素
六、获取父节点和兄弟节点
• 通过具体的节点调用
1. parentNode
属性,表示当前节点的父节点(会接收空格)
代码片段:
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<button id="btn">查找</button>
<script>
window.onload = function(){//等到页面加载结束,再显示
function myClick(idStr , fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
function myClick(idStr , fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
myClick("btn",function(){
var bj=document.getElementById("bj");
var pn=bj.parentNode;
alert(pn.innerHTML);
});
}
</script>
运行结果:
2. previousSibling
属性,表示当前节点的前一个兄弟节点(会接收空格)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul id="city">
<li>上海</li>
<li id="bj">北京</li>
<li>东京</li>
<li>首尔</li>
</ul>
<button id="btn">查找</button>
<script>
window.onload = function(){//等到页面加载结束,再显示
function myClick(idStr , fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
myClick("btn",function(){
var bj=document.getElementById("bj");
var ps=bj.previousSibling;
var pn=bj.previousElementSibling;//不接受空格
alert(ps.innerHTML);
alert(pn.innerHTML);
});
}
</script>
</body>
</html>
3. nextSibling
属性,表示当前节点的后一个兄弟节点
六、元素节点的属性
• 获取,元素对象.属性名
element.value
element.id
element.className
element.src
• 设置,元素对象.属性名=新的值
element.value = “hello”
element.id = “id01”
element.className = “newClass
<body>
name:<input type="text" name="name" id="username" value="abcde"/>
<button id="btn">获取文本框的值并改变</button>
<img id="image" src="/i/eg_smile.gif">
</body>
<script>
/* 定义一个函数,专门用来为指定元素绑定单击响应函数
* 参数:
* idStr 要绑定单击响应函数的对象的id属性值
* fun 事件的回调函数,当单击元素时,该函数将会被触发
*/
function myClick(idStr , fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
myClick("btn",function(){
//获取id为username的元素
var um = document.getElementById("username");
alert(nm.value);
um.value = "今天天气真不错~~~";
});
document.getElementById("myImage").src = "landscape.jpg";
<script>
运行结果:
1
2
3
七、其他属性
• nodeValue
– 文本节点可以通过nodeValue属性获取和设置文本节点的内容
• innerHTML
– 元素节点通过该属性获取和设置标签内部的html代码
部分代码:
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
<li>东京</li>
<li>首尔</li>
</ul>
<button id="btn">获取id为bj的值</button>
<script>
window.onload = function(){//等到页面加载结束,再显示
function myClick(idStr , fun){
var btn = document.getElementById(idStr);
btn.onclick = fun;
}
myClick("btn",function(){
//获取id为bj的元素
var bj = document.getElementById("bj");
//alert(bj.innerHTML);
//alert(bj.innerText);
//获取bj中的文本节点
/*var fc = bj.firstChild;
alert(fc.nodeValue);*/
alert(bj.firstChild.nodeValue);
});
}
</script>
<body>
八、改变CSS样式
代码样例:
<html>
<body>
<p id="p1">Hello World!</p>
<p id="p2">Hello World!</p>
<script>
document.getElementById("p2").style.color = "blue";
document.getElementById("p2").style.fontFamily = "Arial";
document.getElementById("p2").style.fontSize = "larger";
</script>
<p>第二个段落的样式已被脚本修改。</p>
</body>
</html>
运行结果:
<html>
<body>
<h1 id="id1">我的标题</h1>
<button type="button"
οnclick="document.getElementById('id1').style.color = 'red'">
单击我!</button>
</body>
</html>
运行结果:
1
2
注意:如果CSS的样式名中含有-,
* 这种名称在JS中是不合法的比如background-color
* 需要将这种样式名修改为驼峰命名法,
* 去掉-,然后将-后的字母大写
九、使用CSS选择器进行查询
• querySelector()
-只会返回找到的第一个元素
使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个
• querySelectorAll()
-会返回所有符合条件的元素。
即使符合条件的元素只有一个,它也会返回数组
• 这两个方法都是用document对象来调用,两个方法使用相同,都是传递一个选择器字符串作为参数,方法会自动根据选择器字符串去网页中查找元素。
var div = document.querySelector(".box1 div");
var c=document.querySelectorAll("p.hhh");
document.getElementById("demo4").innerHTML="hhh中的文本是:"+c[1].innerHTML;
十、DOM元素增删改
1、添加
document.createElement(val)
可以用于创建一个元素节点对象,
它需要一个标签名作为参数,将会根据该标签名创建元素节点对象,
并将创建好的对象作为返回值返回
document.createTextNode(text)
可以用来创建一个文本节点对象
需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回
appendChild()
向一个父节点中添加一个新的子节点
用法:父节点.appendChild(子节点);
insertBefore()
可以在指定的子节点前插入新的子节点
语法:父节点.insertBefore(新节点,旧节点);
代码样例:
方法一:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
</ul>
<button id="append1">向后添加</button>
<button id="append2">向前添加</button>
<script>
function myClick(id,fun){
var btn=document.getElementById(id);
btn.οnclick=fun;
}
myClick("append1",function(){
var li = document.createElement("li");
var text = document.createTextNode("广州");
li.appendChild(text);
var city=document.getElementById("city");
city.appendChild(li);
});
myClick("append2",function(){
var li = document.createElement("li");
var text = document.createTextNode("广州");
li.appendChild(text);
var city=document.getElementById("city");
var first=city.firstElementChild;
city.insertBefore(li,first);
});
</script>
</body>
</html>
运行结果:
向后添加:
向前添加
方法二:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
</ul>
<button id="append1">添加</button>
<script>
function myClick(id,fun){
var btn=document.getElementById(id);
btn.οnclick=fun;
}
myClick("append1",function(){
//向city中添加广州
var city = document.getElementById("city");
/*
* 使用innerHTML也可以完成DOM的增删改的相关操作
* 一般我们会两种方式结合使用
*/
//city.innerHTML += "<li>广州</li>";
//创建一个li
var li = document.createElement("li");
//向li中设置文本
li.innerHTML = "广州";
//将li添加到city中
city.appendChild(li);
});
</script>
</body>
</html>
运行结果:
替换前:
替换后:
2、替换
replaceChild()
可以使用指定的子节点替换已有的子节点
语法:父节点.replaceChild(新节点,旧节点);
代码样例:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
</ul>
<button id="replace">替换</button>
<script>
function myClick(id,fun){
var btn=document.getElementById(id);
btn.οnclick=fun;
}
myClick("replace",function(){
var li = document.createElement("li");
var text = document.createTextNode("广州");
li.appendChild(text);
var city=document.getElementById("city");
var bj=document.getElementById("bj");
city.replaceChild(li,bj)
});
</script>
</body>
</html>
运行结果:
替换前:
替换后:
3、删除
加粗样式 - removeChild()
可以删除一个子节点
语法:父节点.removeChild(子节点);
子节点.parentNode.removeChild(子节点);
代码样例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
</ul>
<button id="delete">删除</button>
<script>
function myClick(id,fun){
var btn=document.getElementById(id);
btn.οnclick=fun;
}
myClick("delete",function(){
var city=document.getElementById("city");
var last=city.lastElementChild;
// city.removeChild(last);
city.parentNode.removeChild(last);
});
</script>
</body>
</html>
运行结果:
删除前:
删除后:
4、修改
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<ul id="city">
<li id="bj">北京</li>
<li>上海</li>
</ul>
<button id="delete">修改</button>
<script>
function myClick(id,fun){
var btn=document.getElementById(id);
btn.οnclick=fun;
}
myClick("change" , function(){
//获取bj
var bj = document.getElementById("bj");
bj.innerHTML = "昌平";
});
</script>
</body>
</html>
运行结果:
修改前:
修改后:
十一、DOM 事件
事件属性
鼠标/键盘属性
1、当鼠标点击时
代码样例一:
<html>
<body>
<h1 οnclick="this.innerHTML='谢谢!'">请点击此文本!</h1>
</body>
</html>
运行结果:
点击前:
点击后:
代码样例二:
<html>
<body>
<h1 οnclick="changeText(this)">请点击此文本!</h1>
<script>
function changeText(id) {
id.innerHTML = "谢谢!";
}
</script>
</body>
</html>
运行结果:
点击前:
点击后:
2、当域的内容被改变时
onchange 事件经常与输入字段验证结合使用。
<html>
<head>
</head>
<body>
请输入您的名字:<input type="text" id="fname" οnchange="myFunction()">
<script>
function myFunction() {
var x = document.getElementById("fname");
x.value = x.value.toUpperCase();
}
</script>
</body>
</html>
运行结果:
输入时:
输入结束后:
3、当鼠标移入移出时
onmouseover 和 onmouseout 事件可用于当用户将鼠标移至 HTML 元素上或移出时触发某个函数:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div id="areaDiv" style="width:300px;height: 100px;border:1px solid black;margin-bottom:10px;"></div>
<div id="showMsg" style="width:300px;height: 20px;border:1px solid black;"></div>
<script>
var a=document.getElementById("areaDiv");
var s=document.getElementById("showMsg");
a.οnmοusemοve=function(envent){
envent=envent||window.envent;
//clientX可以获取鼠标指针的水平坐标
// cilentY可以获取鼠标指针的垂直坐标
var x=envent.clientX;
var y=envent.clientY;
s.innerHTML="x ="+x+",y = "+y;
}
a.οnmοuseοut=function(){
s.innerHTML="鼠标不在监控范围!";
}
</script>
</body>
</html>
运行结果:
鼠标移出时:
鼠标移入时:
4、当鼠标被点击和释放
- onmousedown, onmouseup 以及 onclick 事件构成了完整的鼠标点击事件。
- 首先当鼠标按钮被点击时,onmousedown 事件被触发;然后当鼠标按钮被释放时,onmouseup
事件被触发;最后,当鼠标点击完成后,onclick 事件被触发。
<html>
<body>
<div id="a" style="width:65px;height:50px;background-color:red;padding: 30px;" οnmοusedοwn="mDown(this)" οnmοuseup="mUp(this)">点击鼠标</div>
<script>
function mDown(obj){
obj.style.backgroundColor="yellow";
obj.innerHTML="松开鼠标";
}
function mUp(obj){
obj.style.backgroundColor="red";
obj.innerHTML="Thinks!";
}
</script>
</body>
</html>
运行结果:
点击前:
点击时:
释放后:
剩余事件,请移步参考文档查询
十二、事件的冒泡与捕获
1.捕获阶段
- 在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
2.目标阶段
- 事件捕获到目标元素,捕获结束开始在目标元素上触发事件
3.冒泡阶段
- 事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
- 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true
一般情况下我们不会希望在捕获阶段触发事件,所以这个参数一般都是false
1、事件的冒泡(Bubble)
- 所谓的冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发
- 在冒泡中,最内侧元素的事件会首先被处理,然后是更外侧的:首先处理 <p> 元素的点击事件,然后是 <div>元素的点击事件。
- 在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box1{
width: 200px;
height: 200px;
background-color: yellowgreen;
}
#s1{
background-color: yellow;
}
</style>
</head>
<body>
<div id="box1">
我是box1
<span id="s1">我是span</span>
</div>
<script type="text/javascript">
//为s1绑定一个单击响应函数
var s1 = document.getElementById("s1");
s1.onclick = function(event){
event = event || window.event;
alert("我是span的单击响应函数");
//取消冒泡
//可以将事件对象的cancelBubble设置为true,即可取消冒泡
//event.cancelBubble = true;
};
//为box1绑定一个单击响应函数
var box1 = document.getElementById("box1");
box1.onclick = function(event){
event = event || window.event;
alert("我是div的单击响应函数");
//event.cancelBubble = true;
};
//为body绑定一个单击响应函数
document.body.onclick = function(){
alert("我是body的单击响应函数");
};
</script>
</body>
</html>
运行结果:
点击span前:
点击span后:(引发各个祖先事件响应)
2、捕获
- 在捕获中,最外侧元素的事件会首先被处理,然后是更内侧的:首先处理 <div> 元素的点击事件,然后是 <p>元素的点击事件。
十三、事件的监听
-
使用 对象.事件 = 函数 的形式绑定响应函数, 它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的
-
addEventListener()
* 通过这个方法也可以为元素绑定响应函数
* 参数:
* 1.事件的字符串,不要on
* 2.回调函数,当事件触发时该函数会被调用
* 3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false -
使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数, 这样当事件被触发时,响应函数将会按照函数的绑定顺序执行
<html>
<body>
<button id="btn">click</button>
<script>
btn.addEventListener("click",function(){
alert("1");
},false);
btn.addEventListener("click",function(){
alert("2");
},false);
</script>
</body>
</html>