注册 登录

清河洛

javascript中的事件绑定和常用事件处理

qingheluo2016-12-16清河洛234
一.W3C事件绑定处理函数“DOM2级事件”定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true表示捕获,false表示冒泡)。window.addEventListener('load', function () {alert('Lee');}, false); W3C的现代事件绑定比我们自定义的好处就是:1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡...

一.W3C事件绑定处理函数

“DOM2级事件”定义了两个方法,用于添加事件和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有DOM节点中都包含这两个方法,并且它们都接受3个参数;事件名、函数、冒泡或捕获的布尔值(true表示捕获,false表示冒泡)。

window.addEventListener('load', function () {alert('Lee');}, false);

W3C的现代事件绑定比我们自定义的好处就是:

1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡和捕获。

window.addEventListener('load', functionName, false); //第一次执行了
window.addEventListener('load', functionName, false); //第二次被屏蔽了

事件冒泡:即从里到外触发。我们可以通过event对象来阻止某一阶段的冒泡。在W3C事件绑定可以设置冒泡和捕获。

box.addEventListener('click', function () { alert('Lee');}, true); //把布尔值设置成true,则为捕获。设置成false,则为冒泡

在最新的W3C规范中,第三个参数现在不知可以传入一个bool来设置是否冒泡了,现在可以传入一个object对象,改对象目前有三个可用的属性(值均为bool值,默认值都是false):

capture:和之前的第三个参数意义相同,即true表示捕获,false表示冒泡
passive: 表示不会取消事件默认行为,浏览器不用等待指定的函数运行完再决定是否执行事件默认行为
    如果同时设置改属性为true并且设置了preventDefault()取消事件默认行为
    则忽略preventDefault()设置并且浏览器发出警告
once: 表明该监听器是一次性的,执行一次后就被自动removeEventListener掉

二.IE事件绑定处理函数

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接受相同的参数:事件名称和函数。

在使用这两组函数的时候,要注意这两组函数与W3C事件处理函数的区别:

1.IE不支持捕获,只支持冒泡;
2.IE添加事件不能屏蔽重复的函数;
3.IE中的this指向的是window而不是DOM对象(实际应用中可以call过去)。
4.在传统事件上,IE是无法接受到event对象的,但使用了attchEvent()却可以,但有些区别。

时间切换器实例(尽兼容IE):

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是无法像W3C那样通过传参接受event对象(要用window.event获取),但如果使用了attachEvent()却可以。

box.attachEvent('onclick', function (evt) {alert(evt);}); //object

IE中的事件绑定函数attachEvent()和detachEvent()可能在实践中不去使用,有几个原因:1.IE9就将全面支持W3C中的事件绑定函数;2.IE的事件绑定函数无法传递this;3.IE的事件绑定函数不支持捕获;4.同一个函数注册绑定后,没有屏蔽掉;5.有内存泄漏的问题。至于怎么替代,我们将在以后的项目课程中探讨。

三.事件对象的其他补充

在W3C提供了一个属性:relatedTarget;这个属性可以在mouseover和mouseout事件中获取从哪里移入和移出到哪里的DOM对象(就是获得操作节点的父节点)。

box.onmouseover = function (evt) {alert(evt.relatedTarget);}//获取移入box最近的那个元素对象

IE提供了两组分别用于移入移出的属性:fromElement和toElement,分别对应mouseover和mouseout。

box.onmouseover = function (evt) {alert(window.event.fromElement.tagName);}; //获取鼠标移入box最近的那个元素对象span
box.onmouseout = function (evt) {alert(window.event.toElement.tagName);}//获取鼠标移出box最近的那个元素对象span

有时我们需要阻止事件的默认行为,比如:一个超链接的默认行为就点击然后跳转到指定的页面。那么阻止默认行为就可以屏蔽跳转的这种操作,而实现自定义操作。

取消事件默认行为还有一种不规范的做法,就是返回false。虽然return false可以实现这个功能,但有漏洞;第一:必须写到最后,这样导致中间的代码执行后,有可能执行不到return false;第二:return false写到最前那么之后的自定义操作就失效了。所以,最好的方法应该是在最前面就阻止默认行为,并且后面还能执行代码。

link.onclick = function (evt) {evt.preventDefault();};//W3C,阻止默认行为,放哪里都可以
link.onclick = function (evt) {window.event.returnValue = false;};//IE,阻止默认行为
function preDef(evt) {//<strong>兼容取消默认行为</strong>
    var e = evt || window.event;
    if (e.preventDefault) {
        e.preventDefault();
    } else {
        e.returnValue = false;
    }
}

上下文菜单事件:contextmenu,当我们右击网页的时候,会自动出现windows自带的菜单。那么我们可以使用contextmenu事件来修改我们指定的菜单,但前提是把右击的默认行为取消掉。

PS:contextmenu事件很常用,这直接导致浏览器兼容性较为稳定。

卸载前事件:beforeunload,这个事件可以帮助在离开本页的时候给出相应的提示,“离开”或者“返回”操作。

addEvent(window, 'beforeunload', function (evt) {
    preDef(evt);
});

鼠标滚轮事件:

非火狐:mousewheel和火狐浏览器:DOMMouseScroll

这两个都是相同的鼠标滚轮事件,只是兼容性的不同,其中mousewheel事件的对象属性wheelDelta和DOMMouseScroll事件的对象detail都用于获取鼠标上下滚轮的距离。

mousewheel事件的对象属性wheelDelta向上滚动一次返回数值120,想下滚动一次返回数值-120。

DOMMouseScroll事件的对象detail向上滚动一次返回数值-4,想下滚动一次返回数值4。

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; //保持计算的统一
}

}

通过浏览器检测可以确定火狐只执行DOMMouseScroll(执行另一个火狐不兼容的滚轮事件火狐并不报错,仅仅是不执行)。



网址导航