事件是每一个元素都具备的能力,绑定事件其实并不是绑定事件本身,而是绑定这个事件被触发时所执行的处理函数。<br />事件 + 事件的反馈 = 前端交互。
绑定事件处理函数
事件句柄绑定方法
传统的绑定方法,兼容性非常的好。但是一个元素的同一个事件只能绑定一个处理函数,如果重复会产生覆盖,且这种绑定的方法只会在事件冒泡阶段执行。(处理函数中的this指向当前元素)
// 内联事件监听器 也是句柄的方式 不建议使用 违背了样式、结构、逻辑分离的原则
<button onclick="..."></button>
elem.onclick = function (ev) {
// ...
}
// 解除绑定
elem.onclick = null;
W3C标准绑定方法
IE9以下不兼容,但是W3C的规范。他的优势是一个元素的同一个事件可以绑定多个处理函数。
(处理函数中的this指向当前元素)
第三个参数可以设置绑定的事件是捕获事件(true)还是冒泡事件(false)。
function handleClick (ev) {
// ...
}
elem.addEventListener('click', handleClick, false);
// 解除绑定
elem.removeEventListener('click', handleClick, false);
IE事件句柄绑定方法
IE8及以下的绑定方法,可以为一个元素同一个事件绑定多个处理函数。(处理函数中的this指向window)
function handleClick (ev) {
// ...
}
elem.attachEvent('onclick', handleClick);
// 解除绑定
elem.detachEvent('onclick', handleClick);
封装兼容性的绑定方法
/**
* addEvent 兼容性绑定事件处理函数
* @param {element} el 要绑定事件元素
* @param {string} type 要绑定的事件类型
* @param {function} fn 要绑定的事件处理函数
*/
function addEvent (el, type, fn) {
if (el.addEventListener) {
el.addEventListener(type, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + type, function () {
fn.call(el);
})
} else {
el['on' + type] = fn;
}
}
事件流
事件流就是页面触发一个事件时,会按照一定的顺序来响应事件,事件的响应过程为事件流。
IE提出事件冒泡流(Event Bubbling)。
Netscape(网景)提出事件捕获流(Event Capturing)。
事件流的三个阶段
- 捕获阶段:事件从window自上而下向目标父节点传播的阶段。
- 目标阶段:真事件到达目标节点(事件源),如果类型指定不冒泡,则事件将在此阶段完成后结束。
- 冒泡阶段:事件从目标父节点开始向上传递至window的阶段。
注:focus、blur、change、submit、reset、select这些事件没有捕获和冒泡现象。IE以及一些除了chrome的老版本的浏览器都没有捕获阶段。
事件源对象
当某个元素触发一个事件时,浏览器会把这个事件触发的详细信息包装成一个对象,传递到此元素绑定的事件处理函数的参数中。(IE浏览器例外,它是放在window.event中)
function handleClick (ev) {
// e 是事件对象 tar 是事件源对象
var e = ev || window.event,
tar = e.target || e.srcElement;
// Firefox 只有 target
// IE 只有 srcElement
}
elem.addEventListener('click', handleClick, false);
事件委托
利于事件冒泡的机制,我们可以把子元素的事件委托给父级,事件触发后会冒泡到父级,我们就可以通过父级的事件处理函数得到真正的事件源对象。
优点:
1、减少多次绑定相同处理函数,性能优化。
2、对于动态增加的元素同样也可以获取到事件源。
3、可以动态获取子元素的下标。
取消冒泡
W3C标准:e.stopPropagation();
IE: e.cancleBubble = true;
/**
* cancleBubble 兼容性取消冒泡
* @param {object} e 事件源对象
*/
function cancelBubble (ev) {
if (e.stopPropagation) {
e.stopPropagation();
} else {
e.cancleBubble = true;
}
}
取消默认事件
a标签的跳转和表单的默认提交。
// return false 只能在句柄的方式中使用。
elem.onclick = function (ev) {
return false;
}
// W3C规范 e.preventDefault(),IE9及以下不兼容
elem.onclick = function (ev) {
var e = ev || window.event;
e.preventDefault();
}
// IE9及以下 e.returnValue = false
elem.onclick = function (ev) {
var e = ev || window.event;
e.returnValue = false;
}