JS基础(三)
dom增删改
- 创建一个元素节点对象
var li=document.createElement("li");//document.createElement()可以用于创建一个元素节点对象,他需要一个标签名作为参数,将会根据该标签名创建元素节点对象。并将创建的对象作为返回值返回
- 创建一个文本节点对象
var tx=document.createTextNode("广州");//document.createTextNode()用于创建一个文本节点对象,需要一个文本类容作为参数,将根据该内容作为参数,并根据该内容创建文本节点,并将新的节点返回
- 向父节点中添加一个新子节点
li.appendChild(tx);//向父节点中添加一个新的子节点,用法:父节点.appendChild(子节点)
整体效果,创建一个广州节点,添加到#city下
mclick("btn1",function(){
var li=document.createElement("li");//可以用于创建一个元素节点对象,他需要一个标签名作为参数,将会根据该标签名创建元素节点对象。并将创建的对象作为返回值返回
var tx=document.createTextNode("广州");//用于创建一个文本节点对象,需要一个文本类容作为参数,将根据该内容作为参数,并根据该内容创建文本节点,并将新的节点返回
li.appendChild(tx);//向父节点中添加一个新的子节点,用法:父节点.appendChild(子节点)
var city=document.getElementById("city");
city.appendChild(li)
})
- 将一个新建元素节点插入到指定元素节点前
//将广州节点插入到#bj前面
mclick("btn2",function(){
var li=document.createElement("li");
var txt=document.createTextNode("广州");
li.appendChild(txt);
var bj=document.getElementById("bj");
var city=document.getElementById("city");
city.insertBefore(li,bj);//insertBefore()可以在指定的节点前插入新子节点,语法insertBefore(新节点,旧节点)
})
- 用新建节点替代指定节点
city.replaceChild(li,bj)//父节点.replaceChild(新节点,旧节点)。可以使用新子节点替换掉已有子节点
- 删除子节点
语法:父节点.removeChild(子节点)
常用:子节点.parentNode.removeChild(子节点) - 读取#city中的HTML代码
先获取city,然后city.innerHTML - 设置#bj内的HTML代码
bj.innerHTML="添加"
使用innerHTML也可以完成 DOM的增删改的相关操作,可以二者结合使用
如:
mclick("btn4",function(){
var li=document.creatElement("li");
var city=document.getElementById("city");
li.innerHTML="广州";//直接改变li中的HTML代码就不用在创建文本节点和向li里面添加文本节点
city.appendChild(li)}
添加删除记录-删除
以下面的例子展示:
<!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>
#tb{border: 1px solid;}
</style>
<script>
window.onload=function(){
var alla=document.getElementsByTagName("a");
for(var i=0;i<alla.length;i++){
alla[i].onclick=function(){
var tr=this.parentNode.parentNode;//注意这里this.parentNode.parentNode中的this不能用alla[i]来代替,因为for循环会在页面加载完后立即执行,而响应函数会在超链接被点击时才执行,响应函数执行时for循环早就执行完毕了,因此i会一直都是3.而返回的alla[i]数组索引最大值为2
var name=tr.getElementsByTagName("td")[0].innerHTML;//获取要删除员工的名字
var la=confirm("确认要"+name+"删除吗?");//显示一段带有信息以及确认按钮和取消按钮的提示框,如果点了确认浏览器会返回true,反之则返回false
if(la){
tr.parentNode.removeChild(tr);}//通过用户的选择来控制这一行代码的执行情况,决定是否删除
return false;//点击超链接后超链接会跳转页面,这是默认行为。但如果不希望出现这个可以通过在响应函数的最后return false 来取消默认行为。也可以将href后的超链接改成"javascript:;"效果相同
}
}
}
</script>
</head>
<body>
<table cellpadding="30px" id="tb" border="1">
<tr>
<th>Name</th>
<th>Email</th>
<th>Salary</th>
<th> </th>
</tr>
<tr>
<td>Tom</td>
<td>Jerry</td>
<td>Bob</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
<tr>
<td>tom@tom.com</td>
<td>Jerry@jerry.com</td>
<td>Bob@Bob.com</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
<tr>
<td>5000</td>
<td>6000</td>
<td>7000</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
</table>
</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>
<style>
#tb{border: 1px solid;}
#w{width: 500px;height: 500px;border: 1px solid;}
</style>
<script type="text/javascript">
function delA(){
var tr=this.parentNode.parentNode;
var name=tr.getElementsByTagName("td")[0].innerHTML;//获取要删除员工的名字
var la=confirm("确认要"+name+"删除吗?");//显示一段带有信息以及确认按钮和取消按钮的提示框,如果点了确认浏览器会返回true,反之则返回false
if(la){
tr.parentNode.removeChild(tr);}//通过用户的选择来控制这一行代码的执行情况,决定是否删除
return false;//点击超链接后超链接会跳转页面,这是默认行为。但如果不希望出现这个可以通过在响应函数的最后return false 来取消默认行为。也可以将href后的超链接改成"javascript:;"效果相同
};//将删除这个响应函数直接提到全局领域,后面直接调用
window.onload=function(){
var allA=document.getElementsByTagName("a");
for(var i=0;i<allA.length;i++){
allA[i].onclick=delA;
}
var bu=document.getElementById("bu");
bu.onclick=function(){
//获取员工信息
var name=document.getElementById("empName").value;
var email=document.getElementById("email").value;
var salery=document.getElementById("salery").value;
//将信息保存到tr中
//创建元素
var tr=document.createElement("tr");
var nameTd=document.createElement("td");
var emailTd=document.createElement("td");
var saleryTd=document.createElement("td");
var atd=document.createElement("td");
var a=document.createElement("a");
//创建文本节点
var nameText=document.createTextNode(name);
var emailText=document.createTextNode(email);
var saleryText=document.createTextNode(salery);
var delText=document.createTextNode("Delete");
//创建tr
nameTd.appendChild(nameText);
emailTd.appendChild(emailText);
saleryTd.appendChild(saleryText);
a.appendChild(delText)
atd.appendChild(a);
tr.appendChild(nameTd);
tr.appendChild(emailTd);
tr.appendChild(saleryTd);
tr.appendChild(atd);
a.href="javascript:;";//为a标签添加href属性
var tbl=document.getElementsByTagName("tbody")[0];
tbl.appendChild(tr);//如果直接向table中添加tr,注意原先的tr都在tbody这个标签中,而新添加的tr在tbody外部,存在隐患当通过tbody来添加tr的样式时,新加进去的tr并不能加上样式。所以要将tr添加到tbody中
a.onclick=delA;
}
}
</script>
</head>
<body>
<table cellpadding="30px" id="tb" border="1">
<tr>
<th>Name</th>
<th>Email</th>
<th>Salary</th>
<th> </th>
</tr>
<tr>
<td>Tom</td>
<td>Jerry</td>
<td>Bob</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
<tr>
<td>tom@tom.com</td>
<td>Jerry@jerry.com</td>
<td>Bob@Bob.com</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
<tr>
<td>5000</td>
<td>6000</td>
<td>7000</td>
<td><a href="deleteEmp?id=001">Delete</a></td>
</tr>
</table>
<div id="w">
<table border="1" cellpadding="20px" id="ne">
<tr><th colspan="4">添加新员工</th></tr>
<tr>
<td colspan="4">name:<input type="text" name="empName" value="尾声" id="empName"></td>
</tr>
<tr>
<td colspan="4">email:<input type="text" name="email" value="am@am.com" id="email"></td>
</tr>
<tr>
<td colspan="4">salery:<input type="text" name="salery" value="2000" id="salery"></td>
</tr>
<tr><td colspan="4"><button id="bu">提交</button></td></tr>
</table>
<div>
</body>
</html>
上面创建tr元素有另外一个办法
var tr=document.createElement("tr")
tr.innerHTML="<td>"+name+"</td>"+
"<td>"+email+"</td>"+
"<td>"+salery+"</td>"+
"<td><a href='javascript:;'>Delete</a></td>";
var A=tr.getElementsByTagName("a")[0];//获取a元素
A.οnclick=delA;//为a标签添加响应函数
var tbl=document.getElementsByTagName("tbody")[0];
tbl.appendChild(tr);
注意这里别直接在tbody中添加tr,因为当写成往tbody中添加元素时,点击提交后虽然也会添加新的tr但是这时整个tbody中的tr都是替换了原先的tr的,这时为原先tr添加的样式就不会起作用了。
使用dom操作css(内联样式)
<!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>
#box1{
width:200px;
height:200px;
background:red;
}
</style>
<script>
window.onload=function(){
//点击按钮后,修改box1的大小
var box1=document.getElementById("box1")
var btn1=document.getElementById("btn1")
btn1.onclick=function(){
//通过js修改元素样式:语法:元素.style.样式名=样式值。注意如果样式名中间有-,如background-color,在js中是不合法的,我们需要把减号去掉然后把减号后面的字母改成大写,及驼峰命名法
box1.style.width="300px"
}
}
</script>
</head>
<body>
<button id="btn1">点击</button>
<div id="box1"></div>
</body>
</html>
js修改的是内联样式,通过内联样式设置的样式都有较高优先级,所以通过js修改的样式往往会立即显示。但是如果在样式后加了!important,此时样式会有最高优先级,即使js也不能覆盖该样式,导致js修改样式失败
读取样式语法:元素.style.样式名
注意通过style属性设置和读取的都是内联样式,无法读取样式表(写在style标签中的样式)中的样式
获取元素的样式
获取元素当前显示的样式
语法:元素.currentStyle.样式名
当前那个样式起作用的是那个就显示哪个。如果没有设置值就会显示他的默认值。但是这个方法只有在IE浏览器中才会起作用
- getComputedStyle()
通过该方法可以在其他浏览器中获取元素当前的样式,这个方法是window的方法,可以直接使用
需要两个参数:
第一个:要获取样式的元素
第二个:可以传递一个伪元素,一般都传null
该方法会返回一个对象。对象中封装了当前元素对应的样式,如果要读取样式写法如下:
var ge=getComputedStyle(box1,null);
alert(ge.width)
或者
alert(getComputedStyle(box1,null).width);
如果获取的样式没有设置则会返回真实的值,例如:width如果没设置值,不会返回一个auto,而是会返回一个值,但是该方法不支持IE8浏览器
注意:通过currentStyle和getComputedStyle()读取到的样式都是只读的不能修改,要修改只有通过style属性
- getStyle()方法
需要两个参数:第一个 obj要获取样式的元素,第二个 name要获取的样式名
function getStyle(obj,name){
if(window.getComputedStyle){
//正常浏览器,具有getComputedStyle()方法
return getComputedStyle(obj,null)[name];
}else{
//IE8的方式,没有getComputedStyle
return obj.currentStyle[name];
}//if后面的条件是window.getComputedStyle,如果判断出浏览器中没有该方法就会返回一个undefined,不影响后面代码的执行
//以上的代码还可以替换为return window.getComputedStyle?getComputeStyle(obj,null)[name]:obj.currentStyle[name]
}
通过该函数来判断浏览器中是否能用该方法,而且保证尽量使用getComputedStyle这个方法,方便我们直观看见对应样式值,调用时格式如下: var ge=getStyle(box1,"width");
其他样式相关属性
- clientWidth和clientHeight
<style>
#box1{
width:200px;
height:200px;
background-color:aqua;
padding:10px;
border:15px solid yellow;
}
</style>
<script>
window.onload=function(){
var box1=document.getElementById("box1");
var btn=document.getElementById("btn")
btn.onclick=function(){
alert(box1.clientWidth);//clientWidth和clientHeight这两个属性可以获取元素的可见宽度和可见高度,这两个属性包括以下属性都是不带px返回都是一个数值,可以直接计算.会获取元素宽度和高度,包括内容区和内边距,但不包括边框。这些属性都是只读的。
}
}
</script>
- offsetWidth和offsetHeight
这两个属性会获取元素的整个的宽度和高度,包括内容区,内边距,和边框, - offsetParent
可以用来获取当前元素的定位父元素
会获取到离当前元素最近的开起了定位的祖先元素,如果所有祖先元素都没开启定位则返回body
<div id="box2" style="position:relative">
<div id="box1"></div>
</div>
var e=box1.offsetParent;
alert(e.id)
- offsetLeft和offsetTop
前一个来获取当前元素相对于其定位父元素的水平偏移量,后一个可以获取当前元素相对于其定位父元素的垂直偏移量 - scrollWidth和scrollHeight
可以获取元素整个滚动区域的宽度和高度 - scrollLeft和scrollTop
获取水平滚动条滚动的距离,获取垂直滚动条滚动的距离
<div id="box2" style="position:relative">
<div id="box1"></div>
</div>
alert(box2.scrollTop);
当满足scrollHeight-scrollTopclientHeight时说明垂直滚动条滚到底了
当scrollWidth-scrollLeftclientWidth说明水平滚动条滚到底了
练习:
<!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>
#inf{
width:300px;
height:200px;
background:blueviolet;
overflow:auto;
}
</style>
<script type="text/javascript">
window.onload=function(){
var inp=document.getElementsByTagName("input");
var inf=document.getElementById("inf");
inf.onscroll=function(){
if(Math.round(inf.scrollHeight-inf.scrollTop)==inf.clientHeight){
inp[0].disabled=false;
inp[1].disabled=false;
}
}//当滚动条滚动到最底部时,按钮设置为可被选中状态
}
</script>
</head>
<body>
<h3>欢迎注册</h3>
<p id="inf">亲爱的用户,请认真阅读顾着,亲爱的用户,请认真阅读顾着,亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着,亲爱的用户,请认真阅读顾着,亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着亲爱的用户,请认真阅读顾着
我已仔细阅读协议</p>
我已仔细阅读协议<input type="checkbox" disabled="disabled" name="xy" />
确认<input type="submit" value="确认" disabled="disabled" name="qr" />
</body>
</html>
事件对象
事件对象
- 当事件的响应函数被触发时。浏览器每次都会将一个事件对象作为实参传递给响应函数
- 在事件对象中封装了当前事件相关的一切信息,比如,鼠标的坐标,键盘按下的是哪一个键,鼠标滚轮滚动的方向…
<script>
window.onload=function(){
var areaDiv=document.getElementById("areaDiv");
var showMsg=document.getElementById("showMsg");
//在鼠标在areaDiv中移动时,在showMsg中来显示鼠标的坐标
//onmousemove该事件将会在鼠标在元素中移动时被触发
areaDiv.onmousemove=function(event){
//在showMsg中显示鼠标的坐标,clientX可以获取鼠标指针的水平坐标,clientY可以获取鼠标指针的垂直坐标
var x=event.clientX;
var y=event.clientY;
showMsg.innerHTML="X="+x+",Y="+y;
}
}
</script>
- 在ie8中,响应函数被触发时,浏览器不会传递事件对象,在ie8及以下浏览器是将对象作为window对象保存的
这时将var x=event.clientX;
改为var x=window.event.clientX;
div随鼠标移动
<!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>
#scl{
width:300px;
height:100px;
background:hotpink;
/*
*开启绝对定位,让后面产生移动
*/
position: absolute;
}
</style>
<script>
window.onload=function(){
var scl=document.getElementById("scl");
document.onmousemove=function(ement){
var x=ement.pageX;
var y=ement.pageY;//pageY和pageX可以获取鼠标相当于当前页面及整个窗口的的坐标
/*var x=ement.clientX;
var y=ement.clientY;*///这里没用clientX的原因是由于clientX和clientY是获取鼠标在当前可见窗口的坐标,而div移动是相当于整个窗口的
/*var st=document.documentElement.scrollTop;
var sh=document.documentElement.scrollLeft;*/
scl.style.left=x+"px";
scl.style.top=y+"px";//将div的位置改成鼠标移动到的坐标
}//这里的事件是给document及整个文档绑定的,因为如果给scl绑定的话就只能当鼠标移到div上才会起作用,范围太小了
}
</script>
</head>
<body style="height:1300px">
<div id="sr"></div>
<div id="scl"></div>
</body>
</html>
如果上面要用client,就要改成如下形式
var x=ement.clientX;
var y=ement.clientY;//这里没用clientX的原因是由于clientX和clientY是获取鼠标在当前可见窗口的坐标,而div移动是相当于整个窗口的
var st=document.documentElement.scrollTop||document.body.scrollTop;
var sh=document.documentElement.scrollLeft||document.body.scrollLeft;
//获取滚动条的距离,在chrome浏览器中认为滚动条是相对于body的,所以用而在其他浏览器中认为滚动条是因为body的父元素容不下body的高度才出现滚动条的,所以在其他浏览器中认为滚动条是body父元素html的,用document.documentElement.scrollLeft来获取滚动条距离。
scl.style.left=x+sh+"px";
scl.style.top=y+st+"px";
事件的冒泡(Bubble)
所谓的冒泡指的是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发,在开发中大部分情况下冒泡是有用的(如上面的div随鼠标移动,id=scl的div在id=sr的div上面移动就是利用了冒泡),如果不希望发生冒泡可以通过事件对象来取消冒泡
方法:对象.cancelBubble=true
<!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>
#btn{
width:500px;
height:100px;
border:1px solid;
background-color: aqua;
position:absolute;
}
#Div{
width:100px;
height:50px;
background:red;
}
</style>
<script>
window.onload=function(){
var s1=document.getElementById("btn");
var s2=document.getElementById("Div");
s1.onclick=function(){
alert("父元素触发");
}
s2.onclick=function(event){
event=event||window.event
alert("子元素触发")
event.cancelBubble=true
}
}
</script>
</head>
<body >
<div id="btn">
<div id="Div"></div>
</div>
</body>
</html>
事件的委派
指将事件统一绑定给元素的共同祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
事件委派利用了冒泡,通过委派可以减少事件绑定次数,提高程序性能
-target
target表示的触发事件的对象
<script>
window.onload=function(){
/*
*为每个超链接绑定一个单击响应函数
*/
var ui=document.getElementById("ui")
var btn1=document.getElementById("btn1");
btn1.onclick=function(){
var li=document.createElement("li");
li.innerHTML="<a href='javascript:;' class='link'>新建超链接</a>";
ui.appendChild(li)
}
ui.onclick=function(event){
if(event.target.className=="link"){
alert("委派");
};
};//通过委派给ul这个父元素添加响应函数,通过target设置当触及到li元素中的链接时函数才会执行
}
</script>
事件的绑定
使用对象.事件==函数的形式来绑定响应函数,这种方法只能同时为一个元素的一个事件绑定响应函数,如果多绑定了后面的会覆盖掉前面的
- addEventListener()通过这种方法也可以为元素绑定响应函数,可绑定多个响应函数,响应函数会按照绑定的顺序执行
- 参数:1,事件的字符串
2,调回函数,当事件触发时该函数会被调用
3,是否在捕获阶段触发事件,需要一个布尔值,一般都传false
如
ui.addEventListener("click",function(){
if(event.target.className=="link"){
alert("委派");
};
},false);//通过委派给ul这个父元素添加响应函数,通过target设置当触及到li元素中的链接时函数才会执行
ui.addEventListener("click",function(event){
if(event.target.className=="link"){
alert("shijian");
};
},false);
注:这个方法不支持IE8以下浏览器,在IE8及以下浏览器中可用attachEvent()来绑定事件
参数:1,事件的字符串要on,2,回调函数
这个方法也可以为一个事件绑定多个函数,不同的是先绑定的后执行,而这个方法在chrome浏览器和火狐浏览器中也不兼容
addEventListener中的this是绑定事件的对象
attachEvent中的this是window
- 定义一个函数用来为指定元素绑定响应函数
参数:1,obj要绑定事件的对象 2,eventStr 事件的字符串 3,callback回调函数
function bind(obj,eventStr,callback){
if(obj.addEventListener){
obj.addEventListener(eventStr,callback,false);
}else{
obj.attachEvent("on"+eventStr,function(){
//在匿名函数中调回函数,使这个方法的this也是事件的对象
callback.call(obj);
})
}
};
在绑定事件的地方再传入参数调用这个函数
事件的传播
关于事件的传播,网景公司和微软公司有不同理解。
微软公司认为事件应该由内向外传播,也就是当事件触发时,应先触发当前元素上的事件
然后向当前元素的祖先元素传播,也就是说事件应该在冒泡阶段执行
网景公司认为事件应该是由外向内传波的,也就是当前事件触发时,应当触发当前元素的最外层祖先元素的事件,然后再向内传播给后代元素(捕获阶段)
w3c中和两个公司的方案,将事件传播分成三个阶段
1,捕获阶段
在捕获阶段时从事件的最外层祖先元素,向目标元素进行事件捕获,但默认此时不会触发事件
2,目标阶段
事件捕获到目标元素后开始在目标元素上触发事件
3,冒泡阶段
事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
如果需要在捕获阶段就触发事件则可以将addEventListener()的第三个参数设置为true,一般情况下不会希望在捕获阶段触发,所以一般设置为false
在IE8以下浏览器中没有捕获阶段