事件流两种顺序:冒泡与捕获。
简单的添加与删除事件
obj.onclick=function(){}
obj.onclick=null;
通用事件添加的删除
obj.addEventListener(),obj.attachEvent()
obj.removeEventListener(),obj.attachEvent()
三个参数分别表示,(事件,绑定函数,事件流),
注意:
1.如果必须得删除事件,这种写法,不能用匿名函数,否则删除函数的时候,不方便。
2.attachEvent的事件名称是onclick,而addEventListener的事件名称是click,且IE中使用的attachEvent()与使用DOM0级方法的的主要区别在于事件处理程序的作用域,在使用dom0级情况下,事件处理程序在其所属元素的作用域内运行,在使用attachEvent()方法的情况下,事件处理程序在全局作用域下运行,其中的this等于window。
封装事件
var EventUtil = {
addHandler: function(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;
}
},
removeHandler: function(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 btn = document.getElementById("btn");
btn.onclick = function(e){
console.log(e);
}
在事件处理程序内部,this始终等于currentTarget值,即currentTarget是指当前被触发或者说正在处理事件的那个元素,而target是指当前的目标元素;比如如下代码,对btn按钮触发点击事件,那么e.currentTraget指向了this,e.target也指向了this;如下代码:
var btn = document.getElementById("btn");
btn.onclick = function(e){
console.log(e.currentTarget == this); // true
console.log(e.target == this); // true
}
但是如果我对document.body触发点击的话,那么e.currentTarget就指向了document.body了,那么e.target 指向与 btn那个元素了,如下代码:
document.body.onclick = function(e){
console.log(e.currentTarget === document.body); // true
console.log(document.body === this); // true
console.log(e.target === document.getElementById("btn")); //true
};
现在应该能理解currentTarget与target的区别吧!currentTarget就是指被点击的那个元素,但是target是当前点击的目标元素,如上代码,由于btn上并没有注册事件,结果click事件就冒泡到了document.body,在那里事件才得到了处理。
标准浏览器下的事件对象是event,比如btn点击后;如下代码:
var btn = document.getElementById("btn");
btn.onclick = function(){
console.log(event); //标准浏览器下打印事件对象
console.log(event.type);//'click'
}
btn.onclick = function(){
// IE下打印的事件对象window.event
console.log(window.event);
console.log(window.event.type); // 'click'
}
上面的写法是在DOM0级上注册事件,如果我们在Dom2级上注册事件的话,那么就会有一个事件对象event作为参数传入事件到函数中,如下:
var btn = document.getElementById("btn");
EventUtil.addHandler(btn,'click',function(e){
console.log(e);
});
在标准浏览器下,在阻止特定事件的默认行为,可以使用preventDefault()方法,比如如下,我点击一个连接,按道理是打开一个新连接窗口,但是我使用preventDefault()方法可以阻止默认行为,阻止打开新窗口;如下代码:
HTML:<a href="http://www.baidu.com" id="alink" target="_blank">打开新连接</a>
JS如下:
var alink = document.getElementById("alink");
alink.onclick = function(e){
console.log(e)
e.preventDefault();
}
就可以阻止页面进行跳转了~ 这是标准浏览器下处理方式,下面我们来看看IE是如何处理默认事件的;
IE下使用returnValue属性来取消给定事件的默认行为,只要将returnValue属性值设置为false即可,就可以阻止浏览器的默认行为,如下代码:
alink.onclick = function(){
console.log(window.event)
window.event.returnValue = false;
}
标准浏览器下使用e.target来指定当前被点击的目标元素,如下代码所示:
var btn = document.getElementById("btn");
btn.onclick = function(){
console.log(event);
console.log(event.target); // 打印事件目标元素
}
IE下是使用event.srcElement来指定当前的目标元素,如下代码:
btn.onclick = function(){
console.log(event);
console.log(window.event.srcElement);
}
在标准浏览器下我们可以使用stopPropagation()方法来停止事件在DOM层次中的传播,即取消事件中的冒泡或者捕获。从而避免触发注册在document.body上面的事件处理程序,如下所示:
var btn = document.getElementById("btn");
btn.onclick = function(e){
alert(1);
e.stopPropagation();
}
document.body.onclick = function(){
alert(2);
}
如上代码,如果我不使用stopPropagation()阻止冒泡事件的话,那么在页面中会先弹出1,然后弹出2,如果使用stopPropagation()方法的话,只会在页面上弹出1,就不会冒泡到body上面去;
IE下停止冒泡的话,我们可以使用cancelBubble属性,我们只要将此属性设置为true,即可阻止事件通过冒泡触发document.body中的注册事件。但是IE是不支持捕获事件的,但是stopPropagation()即支持捕获事件又支持冒泡事件的。如下代码:
btn.onclick = function(e){
alert(1);
window.event.cancelBubble = true;
}
document.body.onclick = function(){
alert(2);
}
如果不设置window.event.cancelBubble 为true的话,就会先弹出1,然后弹出2,如果加上的话,就只会弹出1对话框。
理解了上面的区别后,我们现在可以往EventUtil对象里面添加跨浏览器的方法了;
var EventUtil = {
addHandler: function(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;
}
},
removeHandler: function(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;
}
},
getEvent: function(event) {
return event ? event : window.event;
},
getTarget: function(event) {
return event.target || event.srcElement;
},
preventDefault: function(event){
if(event.preventDefault) {
event.preventDefault();
}else {
event.returnValue = false;
}
},
stopPropagation: function(event) {
if(event.stopPropagation) {
event.stopPropagation();
}else {
event.cancelBubble = true;
}
}
};
内容太多,不方便一次传播
下次内容有
ui事件(用户交互)
load事件
焦点事件
鼠标事件
客户区坐标
页面坐标
滚动事件
,。。
。。。
本文分享自 交互设计前端开发与后端程序设计 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!