事件流
事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候,那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。
事件冒泡,是从里往外逐个触发。事件捕获,是从外往里逐个触发。那么现代的浏览器默认情况下都是冒泡模型,而捕获模式则是早期的Netscape默认情况。而现在的浏览器要使用DOM2级模型的事件绑定机制才能手动定义事件流模式。
事件冒泡
--------事件由最开始的元素接收,让后逐级向上传播到最不具体的那个节点(文档)
你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省级,直至到中央法院,最终使你的案件得以处理。
事件捕获
--------事件由最最不具体的那个节点(文档)元素接收,让后逐级向下广播到最具体的那个元素
你在地方法院要上诉一件案子,如果地方没有处理此类案件的法院,地方相关部门会帮你继续往上级法院上诉,比如从市级到省级,直至到中央法院,最终使你的案件得以处理。
W3C事件处理函数
DOM2级事件”定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true表示捕获,false表示冒泡)。
window.addEventListener('load', function () {
alert('Mumu);
}, false);
window.addEventListener('load', function () {
alert('Mumu');
}, false);
W3C的现代事件绑定比我们自定义的好处就是:1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡和捕获。
window.addEventListener('load', init, false); //第一次执行了
window.addEventListener('load', init2, false); //第一次执行了
IE事件处理函数
IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的参数:事件名称和函数。
在使用这两组函数的时候,先把区别说一下:
- IE不支持捕获,只支持冒泡;
- IE中的this指向的是window而不是DOM对象。
3 在传统事件上,IE是无法接受到event对象的,但使用了attchEvent()却可以,但有些区别。
window.attachEvent('onload', function () {
var box = document.getElementById('box');
box.attachEvent('onclick', toBlue);
});
function toRed() {
var that = window.event.srcElement;
that.className = 'red';
that.detachEvent('onclick', toRed);
that.attachEvent('onclick', toBlue);
}
function toBlue() {
var that = window.event.srcElement;
that.className = 'blue';
that.detachEvent('onclick', toBlue);
that.attachEvent('onclick', toRed);
}
IE 事件里面的this==window
window.attachEvent('onload', function () {
var box = document.getElementById('box');
box.attachEvent('onclick', function () {
alert(this === window); //this指向的window
});
});
IE 无法通过传参接受event对象
在传统绑定上,IE是无法像W3C那样通过传参接受event对象,但如果使用了attachEvent()却可以。
box.onclick = function (evt) {
alert(evt); //undefined
}
box.attachEvent('onclick', function (evt) {
alert(evt); //object
alert(evt.type); //click
});
box.attachEvent('onclick', function (evt) {
alert(evt.srcElement === box); //true
alert(window.event.srcElement === box); //true
});
IE&W3C事件兼容(选学)
···
function addEvent(obj, type, fn) { //添加事件兼容
if (obj.addEventListener) {
obj.addEventListener(type, fn);
} else if (obj.attachEvent) {
obj.attachEvent('on' + type, fn);
}
}
function removeEvent(obj, type, fn) { //移除事件兼容
if (obj.removeEventListener) {
obj.removeEventListener(type, fn);
} else if (obj.detachEvent) {
obj.detachEvent('on' + type, fn);
}
}
function getTarget(evt) { //得到事件目标
if (evt.target) {
return evt.target;
} else if (window.event.srcElement) {
return window.event.srcElement;
}
}
···
1.IE9就将全面支持W3C中的事件绑定函数;
2.IE的事件绑定函数无法传递this;
3.IE的事件绑定函数不支持捕获;
阻止事件的默认行为
方法二:
W3C:evt.preventDefault();
IE: evt.returnValue = false
function prevDefault(evt) {
var e = evt || window.event;
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
};
鼠标滚轮
鼠标滚轮(mousewheel)和DOMMouseScroll,用于获取鼠标上下滚轮的距离。
addEvent(document, 'mousewheel', function (evt) { //非火狐
alert(getWD(evt));
});
addEvent(document, 'DOMMouseScroll', function (evt) { //火狐
alert(getWD(evt));
});
function getWD(evt) {
var e = evt || window.event;
if (e.wheelDelta) {
return e.wheelDelta;
} else if (e.detail) {
return -evt.detail * 30; //保持计算的统一
}
}
手机事件
touchstart:触摸开始的时候触发
touchmove:手指在屏幕上滑动的时候触发
touchend:触摸结束的时候触发
事件属性
targetTouches:位于当前DOM元素上手指的列表。
client / clientY:// 触摸点相对于浏览器窗口viewport的位置
pageX / pageY:// 触摸点相对于页面的位置
e.targetTouches[0].pageX 获取到