javascript高级程序设计笔记-第十三章(事件)

一、事件流

事件流包括三个阶段:事件捕获阶段、处于目标阶段、时间冒泡阶段。

如图:捕获阶段是逐级向下,由不具体到具体节点;冒泡阶段是逐级向上传播到不具体的节点

二、事件处理程序

1、HTML事件处理程序

通过使用一个与相应事件处理程序同名的HTML特性来指定

<input type="button" value="click" onclick="alert('hi')">

2、DOM0级事件处理程序

将一个函数赋值给一个事件处理程序属性(每个元素都有自己的事件处理程序属性)

var btn = document.getElementById("myBtn");
btn.onclick = function() {
	alert("hi");
};

使用DOM0级方法指定的事件处理程序是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行,即this引用当前的元素

var btn = document.getElementById("myBtn");
btn.onclick = function() {
	alert(this.id);
};

删除事件处理程序

btn.onclick = null;

3、DOM2级事件处理程序

addEventListener()removeEventListener()用于处理指定和删除事件处理程序的操作。接收3个参数:事件名、事件处理函数、布尔值。如果布尔值是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序。

var btn = document.getElementById('myBtn');
btn.addEventListener("click", function() {
	alert(this.id);
}, false);
//事件处理程序是在元素的作用域中运行,即this引用当前的元素

通过addEventListener()添加的事件处理程序只能用removeEventListener()移除;移除时传入的参数与添加处理程序时使用的参数相同。(添加的匿名函数无法移除)

var btn = document.getElementById('myBtn');
btn.addEventListener("click", function() {
	alert(this.id);
}, false);
btn.removeEventListener("click", function() {
	alert(this.id);
}, false);		//无效

//将匿名函数赋值给变量
var btn = document.getElementById('myBtn');
var handler = function() {
	alert(this.id);
};
btn.addEventListener("click", handler, false);
btn.removeEventListener("click", handler, false);	//有效

4、IE事件处理程序(IE8及更早版本)

attachEvent()detachEvent(),接收2个参数:事件名、事件处理函数

除了事件处理程序的作用域不一样外,其他类似。IE事件处理程序在全局作用域中运行

var btn = document.getElementById('myBtn');
var handler = function() {
	alert(this === window);
};
btn.attachEvent("onclick", handler);	//true
btn.detachEvent("onclick", handler);

5、跨浏览器的事件处理程序

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;
		}
	}
};

//使用EventUtil对象
var btn = document.getElementById('myBtn');
var handler = function() {
	alert("hi");
};
EventUtil.addHandler(btn, "click", handler);

三、事件对象

1、DOM中的事件对象

在事件处理程序内部,对象this始终等于currentTarget的值,而target则只包含事件的实际目标

如果将事件处理程序指定给了目标元素,则this、currentTarget、target包含的值相同

var btn = document.getElementById('myBtn');
btn.onclick = function(event) {
	alert(this === event.currentTarget);	//true
	alert(this === event.target);			//true
};

如果事件处理程序存在于父节点中,单击当前元素时

var btn = document.getElementById('myBtn');
document.body.onclick = function(event) {
	alert(document.body === event.currentTarget);	//true
	alert(document.body === this);					//true
	alert(btn = event.target);						//true
};

使用type属性,通过一个函数处理多个事件

var btn = document.getElementById('myBtn');
var handler = function(event) {
	switch(event.type) {
		case "click":
			alert("hi");
			break;
		case "mouseover":
			event.target.style.backgroundColor = "red";
			break;
		case "mouseout":
			event.target.style.backgroundColor = "";
			break;
	}
};

btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;

preventDefault()方法,阻止特定事件的默认行为(只有在cancelable属性为true时才能使用)

var link = document.getElementById('myLink');
link.onclick = function(event) {
	event.preventDefault();
};

stopPropagation()方法,取消事件的进一步捕获和冒泡(只有在cancelable属性为true时才能使用)

var btn = document.getElementById('myBtn');
btn.onclick = function(event) {
	alert("hi");
	event.stopPropagation();
};
document.body.onclick = function(event) {
	alert("hi again");
};
//如果不使用stopPropagation(),单击按钮时,就会先后出现两次警告框

2、IE中的事件对象

在使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在。即window.event

var btn = document.getElementById('myBtn');
btn.onclick = function(event) {
	var event = window.event;
	alert(event.type);
};
//通过window.event取得event对象

使用attachEvent()添加事件处理程序时,event对象作为参数被传入事件处理函数

var btn = document.getElementById('myBtn');
btn.attachEvent("onclick", function(event) {
	alert(event.type);
});

srcElement属性,表示事件的目标(与DOM中的target属性相同)

var btn = document.getElementById('myBtn');
btn.onclick = function() {
	alert(window.event.srcElement === this);	//true
};
//都指向btn元素
btn.attachEvent("onclick", function(event) {
	alert(event.srcElement === this);			//false
});
//event.srcElement指向btn元素,this指向全局作用域window

returnValue属性,默认为true,设置为false时可以取消事件的默认行为(与DOM中的preventDefault()方法相同)

var link = document.getElementById('myLink');
link.onclick = function() {
	window.event.returnValue = false;
};

cancelBubble属性,与DOM中的stopPropagation()方法类似,默认为false,设置为true时可以取消事件的冒泡

var btn = document.getElementById('myBtn');
btn.onclick = function() {
	alert("hi");
	window.event.cancelBubble = true;
};
document.body.onclick = function() {
	alert("hi again");
};
//设置为true,单击按钮,只显示一个警告框

3、跨浏览器的事件对象

var EventUtil = {
	getEvent: function(event) {					//取得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;
		}
	}
};

四、事件委托

只指定一个事件处理程序,就可以管理某一类型的所有事件

<ul id="myLinks">
	<li id="dosomething">do something</li>
	<li id="gosomewhere">go somewhere</li>
	<li id="sayhi">say hi</li>
</ul>

传统:

var item1 = document.getElementById('dosomething');
var item2 = document.getElementById('gosomewhere');
var item3 = document.getElementById('sayhi');

EventUtil.addHandler(item1, "click", function(event) {
	document.title = "other title";
});
EventUtil.addHandler(item2, "click", function(event) {
	location.href = "http://baidu.com";
});
EventUtil.addHandler(item3, "click", function(event) {
	alert("hi");
});

事件委托:

var list = document.getElementById('myLinks');
EventUtil.addHandler(list, "click", function(event) {
	event = EventUtil.getEvent(event);
	var target = EventUtil.getTarget(event);
	switch(target.id) {
		case "dosomething":
			document.title = "other title";
			break;
		case "gosomewhere":
			location.href = "http://baidu.com";
			break;
		case "sayhi":
			alert("hi");
			break;
	}
});
posted @ 2016-03-09 14:11  u14e  阅读(320)  评论(0编辑  收藏  举报