为节省页面,所有代码均写在<body></body>内。
事件
-
事件是文档或浏览器中发生的某些特定的交互瞬间。
JavaScript
和HTML
之间的交互都是通过事件。(拖动滚动条、鼠标滑动、点击等) -
事件流:从页面中接受事件的顺序。
选择某个按钮同时,也会触发这个按钮的容器,接着触发上级容器,button-->div-->...-->body-->html-->document
(事件冒泡流)。
事件流的种类
-
事件冒泡流:指事件最开始由最具体的元素(文档中嵌套层数最深的节点)接收,然后逐级向上传播至
document
节点。(IE8之前浏览器只支持事件冒泡,并且不支持DOM2级事件处理程序)
button-->div-->...-->body-->html-->document
-
事件捕获:不太具体的节点最先接收到事件,最具体的节点最后接收到事件。(与事件冒泡流截然相反,老版本IE浏览器不支持事件捕获,所以慎用,可以放心使用事件冒泡流模型)。
document-->html-->body-->...-->div-->button
- 实例
<html>
<head></head>
<body>
<div>
<input type = "button" id = "btn" onclick = "function() {}"/>
</div>
</body>
</html>
事件冒泡:浏览器会认为在"onclick"
按钮时,先触发按钮的事件,再依次向上传递,触发上级标签(parentNode
)绑定的事件。
- 阻止事件冒泡:
event.stopPropagation();
,(event
是一个事件对象) - 阻止事件的默认行为:
event.preventDefault();
(阻止事件的默认行为,类似a
标签的跳转超链接)
事件处理程序
- HTML事件处理程序:直接在HTML标签内添加事件。
<div>
<!--在html标签内直接添加事件-->
<input type = "button" id = "btn" onclick = "showMes()"/>
</div>
<script>
function showMes()
alert("hello world");
}
</script>
缺点:HTML与JavaScript代码紧密耦合在一起,如果需要更改事件的处理方法,需要同时修改html
和js
中的代码,不便于修改。不推荐使用
-
DOM0级事件处理程序:
传统方式:将函数赋值给一个事件的处理程序属性。使用较多,并且简单易用,跨浏览器
<input type="button" value="按钮1" id="btn1" onclick="showMes()"> <!--html内调用事件,不推荐使用-->
<input type="button" value="按钮2" id="btn2">
<script>
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
//
function showMes() {
alert("hello world");
}
btn2.onclick = showMes; //将单击事件属性添加给按钮2属性,并且赋值为showMes
btn2.onclick = null; //不想要该事件时,可以赋值null删除事件
</script>
优点:只需在js
代码中修改添加的事件,降低代码的耦合,便于维护。注意btn2.onclick = showMes
,没有括号。通过btn2.onclick = null;
删除事件
-
DOM2级事件处理程序
DOM2级事件指定两个方法:用于指定处理和删除事件的操作。addEventListener(event,handler,bool)
和removerEventListener(event,handler, bool)
两个方法。(所有DOM节点都包含这两个方法,并且包含三个参数,两个方法的参数完全相同)。
event
:指需要处理的事件名,click
,mouseover
等,注意少了字符on
handler
:指作为事件处理程序的函数,触发相应事件后运行的js
函数。
bool
:true
表示采用事件捕获模型(在捕获阶段调用事件处理程序),false
表示采用事件冒泡模型(在冒泡阶段调用事件处理程序),由于通常使用事件冒泡模型,所有多数情况为false
(添加到冒泡阶段可以兼容大多数浏览器)。
<input type="button" value="按钮3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
//
function showMes() {
alert("hello world");
}
btn3.addEventListener("click", showMes, false); //去掉on
btn3.removeEventListener("click", showMes, false);
</script>
注意:去掉调用事件类型前的"on"
,只需要"click"
;通过addEventListener()
方法添加的事件 只能通过removerEventListener()
方法删除,并且两个方法中的参数相同。
通过DOM0级和DOM2级事件处理程序,可以为一个元素添加多个事件处理程序(也可以添加多个事件),按照添加的顺序执行。
<input type="button" value="按钮3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//在一个元素上添加多个事件
btn3.addEventListener("click", showMes, false);
btn3.addEventListener("click", function() {
alert(this.value); //弹出按钮3的value属性。
}, false);
</script>
注:结果会一次弹出两个窗口,先是showMes
窗口,单击后再显示匿名函数窗口。this
参数引用被触发的元素。
IE事件处理程序
IE不支持addEventListener()
和removeEventListener()
两个方法,它自定义attachEvent(event, handler)
和detachEvent(event, handler)
两个方)法。接受相同的两个参数(事件名称,事件处理函数),IE默认使用事件冒泡模型,所以不需要第三个布尔参数。
注:IE的event
参数需要加上"on"
,像"onclick"
、"onmouseover"
。
<input type="button" value="按钮3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//在一个元素上添加多个事件,加上on
btn3.attachEvent("onclick", showMes);
btn3.detachEvent("onclick", function() {
alert(this.value); //弹出按钮3的value属性。
});
</scirp>
兼容IE的方法
由于IE和其他浏览器的DOM2级事件处理程序方法不同,需要做兼容性设置。采用恰当的检测来解决,最好将方法封装在对象将对象赋值给变量方便调用。
<input type="button" value="按钮3" id="btn3">
<script>
var btn3 = document.getElementById("btn3");
function showMes() {
alert("hello world");
}
//给对象封装两个方法,添加事件和删除事件
var eventUtil = {
//添加事件
addHandler: function(element, event, handler) {
if(element.addEventListener){ //如果元素有封装addEventListener方法
element.addEventListener(event, handler, false);
} else if(element.attachEvent) { //如果元素有封装attachEvent方法
element.attachEvent("on"+event, handler); //注意IE需要加上'on'
} else {
element["on"+event] = handler; //不支持DOM2级的方法,使用DOM0级方法增加,并且使用方括号,注意'on'
}
}, //注意逗号
//删除事件
removeHandler: function(element, event, handler) {
if(element.removeEventListener){ //如果元素有封装addEventListener方法
element.removerEventListener(event, handler, false);
} else if(element.detachEvent) { //如果元素有封装attachEvent方法
element.detachEvent("on"+event, handler); //注意IE需要加上'on'
} else {
element["on"+event] = null; //不支持DOM2级的方法,使用DOM0级方法增加,并且使用方括号,注意'on'
}
}
}
eventUtil.addHandler(btn3, "click", showMes); //传入"click"
eventUtil.removeHandler(btn3, "click", showMes); //删除事件
</scirp>
注意:两个对象方法之间用,
隔开,传入的参数使用"click",注意在不知道属性名称时使用方括号访问。