一:事件流
事件流描述的是从页面中接收事件的顺序。但 IE 的事件流是事件冒泡流,而 Netscape Communicator 的事件流是事件捕获流。
1.事件冒泡
IE 的事件流叫做事件冒泡,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播到较为不具体的节点(文档)。
如果click页面中的div元素,先是触发div上的绑定事件,然后是body上的绑定事件,再然后是html,知道document对象。
IE9、Firefox、Chrome 和 Safari 将事件一直冒泡到 window 对象。
2.事件捕获
事件捕获与事件冒泡相反,认为最不具体的节点应该更早接收事件。
如果click页面中的div元素,先是由document节点接收到事件,然后是html,再然后是body触发事件,最后是div元素触发事件。
IE9、Safari、Chrome、Opera和 Firefox 目前也都支持这种事件流模型,但是都是从window对象开始接收事件。
3.DOM事件流
DOM2级事件规定,事件流包括3个阶段,(捕获阶段、目标阶段、冒泡阶段)。
用户操作事件开始,先是捕获,从document节点开始,到div节点之前,捕获结束,开始目标阶段,表示div节点接收到事件,然后开始冒泡。
“DOM2 级事件”规范明确要求捕获阶段不会涉及事件目标,就是在捕获阶段不会触发绑定事件。在冒泡阶段会触发绑定事件(目标阶段属于冒泡阶段),如上图点击div元素,会在4,5,6,7触发绑定事件,1,2,3则不触发
IE9、Safari、Chrome、Firefox 和 Opera 9.5 及更高版本都会在捕获阶段触发事件对象上的事件。结果,就是有两个机会在目标对象上面操作事件。IE8不支持DOM事件流。
二.绑定事件
1.DOM0级绑定事件
<input type="button" value="Click Me1" onclick="console.log(this.value)" />
<input type="button" value="Click Me2" onclick="console.log(event.target.value)" />
<input type="button" value="Click Me3" onclick="clickMe3(event)" />
<input type="button" value="Click Me4" id="clickMe4"/>
<script>
function clickMe3 (event){
console.log(this)
console.log(event.target.value)
}
var btn = document.getElementById("clickMe");
btn.onclick = function(event){
console.log(this)
console.log(event)
}
</script>
若使用clickMe3的绑定事件方法需注意函数内的this指向,它指向window,作用域为全局。
DOM0级绑定事件方法不能在其中使用未经转义的 HTML 语法字符,例如和号(&)、双引号(" ")、小于号(<)或大于号(>)。可转义后使用,如下
<input type="button" value="Click Me" onclick="alert("Clicked")" />
DOM0级绑定事件方法应用很广泛。
需注意的是,如果js内容过多或其他异步问题,导致绑定事件时并不及时,可能造成DOM元素渲染完成后短时间内并没有绑定事件,用户点击了并没有效果。
若要解除绑定 btn.onclick = null 即可。
2.DOM2 级事件处理程序
addEventListener()和removeEventListener()为DOM2级事件,每个DOM都有这两个方法,且接收3个参数(事件名,回调函数,布尔值)
<input type="button" value="Click Me" id="clickMe"/>
<script>
var btn = document.getElementById("clickMe");
btn.addEventListener("click",function(event){
console.log(this)
console.log(event)
},false)
</script>
addEventListener()三个参数中,click为触发事件类型,回调函数为触发事件后的回调,布尔值为表示在什么阶段触发,为true时在捕获阶段触发,为false时在冒泡阶段触发。可省略,默认为false
var btn = document.getElementById("clickMe");
function clickMe() {
console.log("click Me")
}
btn.addEventListener("click", clickMe, false)
btn.removeEventListener("click", clickMe, false)
removeEventListener()方法为解除事件绑定,与addEventListener()用法一样。不可将回调函数写成匿名函数,不然无法解除绑定
<input type="button" value="Click Me" id="clickMe"/>
<script>
var btn = document.getElementById("clickMe");
btn.addEventListener("click",function(){
console.log(1)
},false)
btn.addEventListener("click",function(event){
console.log(2)
},false)
</script>
多次绑定将会多次触发,按照绑定顺序先输出1,后输出2
3.IE绑定事件
IE浏览器的DOM元素都有attachEvent()和 detachEvent()方法。接收两个参数(绑定事件,回调函数),因为IE8及以前版本只支持冒泡事件,所以attachEvent()方法会在冒泡阶段触发。
<input type="button" value="Click Me" id="clickMe"/>
<script>
var btn = document.getElementById("clickMe");
btn.attachEvent("onclick",function(){
console.log(this)
})
btn.detachEvent("onclick",function(event){
console.log(event)
})
function removeClickMe(){
console.log("remove")
}
btn.attachEvent("onclick",removeClickMe)
btn.detachEvent("onclick",removeClickMe)
</script>
1.attachEvent()方法中htis指向window
2.绑定事件名需要加‘on’
3.IE8及以前多次绑定触发顺序为先绑定、后触发(先输出event,后输出this)
4.IE8以后多出绑定触发顺序为先绑定,先触发(先输出this,后输出event)
5,removeClickMe()方法删除时不允许使用匿名函数
4.跨浏览器绑定事件方法兼容
<input type="button" value="Click Me" id="clickMe" />
<script>
var btn = document.getElementById("clickMe");
function addHandler(element, type, handler) {
if (element.addEventListener) {
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent("on" + type, handler);
} else {
element["on" + type] = handler;
}
}
function removeHandler(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.detachEvent) {
element.detachEvent("on" + type, handler);
} else {
element["on" + type] = null;
}
}
var handler = function (event) {
console.log(this);
console.log(event);
};
addHandler(btn, "click", handler);
</script>
这两个方法接受 3 个参数:要操作的元素、事件名称和事件处理程序函数。
三.事件对象
1.event 对象
上面代码中出现的event是当前绑定事件的节点对象,这个对象中包含着所有与事件有关的信息。如图
2.event对象包含的常用属性及方法
event.target
等价于之前代码中的this,也就是绑定事件的元素本身,打印效果如图
IE中使用event.srcElement来获取元素目标
event.preventDefault()
阻止默认行为,可以阻止a标签的href的默认跳转等默认行为
IE中使用event.returnValue = false来达到阻止默认行为的效果
event.stopPropagation()
该方法用于立即停止事件在 DOM 层次中的传播,即取消进一步的事件捕获或冒泡
<input type="button" value="Click Me" id="clickMe" />
<script>
var btn = document.getElementById("clickMe");
btn.onclick = function (event) {
console.log("Clicked");
event.stopPropagation();
};
document.body.onclick = function (event) {
console.log("Body clicked");
};
</script>
body上的绑定事件将不执行、
PS:欢迎大家指正补充
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)