JavaScript 事件绑定及深入

前端之家收集整理的这篇文章主要介绍了JavaScript 事件绑定及深入前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

事件绑定分为两种:

一种是传统事件绑定(内联模型/脚本模型);上一章内容; 一种是现代事件绑定(DOM2级模型);现代事件绑定在传统事件绑定基础上提供了更强大的功能; 一 传统事件绑定的问题

函数赋值给一个事件处理函数; var Box = document.getElementById('Box'); // 获取元素; Box.onclick = function(){ // 元素点击触发事件; alert('Lee'); }

// 问题一:一个事件处理函数触发两次事件;
window.onload = function(){ // 第一组程序;
alert('Lee');
}
window.onload = function(){ // 第二组程序;
alert('Mr.Lee');
}
// PS:当两组程序同时执行的时候,后面一个会把前面一个完全覆盖;
// 导致前面的window.onload完全失效了;
// 解决方案:
window.onload = function(){ // 第一组事件处理程序,会被覆盖;
alert('Lee');
}
if(typeof window.onload == 'function'){ // 判断之前是否有window.onload;
var saved = null; // 创建一个保存器;
saved = window.onload; // 把之前的window.onload保存起来;
}
window.onload = function(){ // 下一个要执行的事件;
// saved()=window.onload = function
if(saved)saved(); // 判断之前是否有事件,如果有则先执行之前保存的事件;
alert('Mr.Lee'); // 执行本事件的代码;
}

Box.onclick = boBlue; // 第一次执行toBlue(); function toRed(){ this.className = 'red'; this.onclick = toBlue; // 第三次执行roBlue(),然后来回切换; } function toBlue(){ this.className = 'blue'; this.onclick = toRed; // 第二次执行toRed(); } // 这个切换器在扩展的时候,会出现一些问题: 1.如果增加一个执行函数,那么会被覆盖; Box.onclick = toAlert; // 被增加函数; Box.onclick = toBlue; // toAlert被覆盖了;

2.如果解决覆盖问题,就必须包含同时执行;
Box.onclick = function(){ // 包含进去,但可读性降低;
toAlert(); // 第一次不会被覆盖,但第二次又被覆盖;
toBlue.call(this); // 还必须把this传递到切换器里;
}

自定义事件处理函数; function addEvent(obj,type,fn){ // 取代传统事件处理函数; var saved = null; // 保存每次触发的事件处理函数; if(typeof obj['on'+type] == 'function'){// 判断是不是存在事件; saved = obj['on'+type]; // 如果有,保存起来; } obj['on'+type] = function(){ // 然后执行; if(saved)saved(); // 执行上一个; fn.call(this); // 执行函数,把this传递进去; } } addEvent(window,'load',function(){ alert('Lee'); // 可以执行; }); addEvent(window.'load',function(){ alert('Mr.Lee'); // 可以执行; })

// 用自定义事件函数注册到切换器上查看效果:
addEvent(window,function(){
var Box = document.getElementById('Box');
addEvent(Box,'click',toBlue);
});
function toRed(){
this.className = 'red';
addEvent(this,toBlue);
}
function toBlue(){
this.className = 'blue';
addEvent(this,toRed);

二 W3C事件处理函数

// "DOM2级事件"定义了两个方法,用于添加事件和删除事件的处理程序:addEventListener()和removeEventListener();

方法,并且它们都接收3个参数:事件名/函数/冒泡或捕获的布尔值(true表示捕获,false表示冒泡); window.addEventListener('load',function(){ alert('Lee'); },false); window.addEventListener('load',function(){ alert('Mr.Lee'); },false); // PS:W3C的事件绑定好处:1.不需要自定义了;2.可以屏蔽相同的函数;3.可以设置冒泡和捕获; window.addEventListener('load',init,false); // 第一次执行了; window.addEventListener('load',false); // 第二次被屏蔽了; function init(){ alert('Lee'); }

// 事件切换器
window.addEventListener('load',function(){
var Box = document.getElementById('Box');
Box.addEventListener('click',function(){ // 不会被覆盖/误删;
alert('Lee');
},false);
Box.addEventListener('click',toBlue,false); // 引入切换;
},false);

function toRed(){
this.className = 'red';
this.removeEventListener('click',toRed,false); // 移除事件处理函数;
this.addEventListener('click',false); // 添加需要切换的事件处理函数;
}

function toBlue(){
this.className = 'blue';
this.removeEventListener('click',false);
this.addEventListener('click',false);
}

// 设置冒泡和捕获阶段
document.addEventListener('click',function(){
alert('document');
},true); // 设置为捕获;

document.addEventListener('click',false); // 设置为冒泡;

三 IE事件处理函数

// IE中实现了与DOM中类似的两个方法:attachEvent()和detachEvent();

// 这两个方法接收相同的参数:事件名和函数;

<div class="jb51code">
<pre class="brush:js;">
// 在使用这两组函数的时候,区别:
// 1.IE不支持捕获,只支持冒泡;
// 2.IE添加事件不能屏蔽重复的函数;
// 3.IE中的this指向的是window而不是DOM对象;
// 4.在传统事件上,IE是无法接受到event对象的;但使用了attachEvent()却可以;
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);
}
// PS:IE不支持捕获;
// IE不能屏蔽;
// IE不能传递this,可以call过去;

// 在传统绑定上,IE是无法像W3C那样通过传参接受event对象;但如果使用了attachEvent()却可以;
Box.onclick = function(evt){
alert(evt); // undefined;
}

Box.attachEvent('onclick',function(evt){
alert(evt); // object;
alert(evt.type); // click;
});

// 兼容IE和W3C的事件切换器函数;
function addEvent(obj,fn){ // 添加事件处理程序兼容;
if(obj.addEventListener){
obj.addEventListener(type,fn);
}else if(obj.attachEvent){
obj.attachEvent('on'+type,fn);
}
}

function removeEvent(obj,fn){ // 移除事件处理程序兼容;
if(obj.removeEventListener){
obj.removeEventListener(type,fn);
}esle if(obj.detachEvent){
obj.detachEvent('on'+type,fn);
}
}

function getTarget(evt){ // 得到事件目标;
if(evt.target){
return evt.target;
}else if(window.event.srcEleemnt){
return window.event.srcElement;
}
}

四 事件对象补充

属性可以在mouSEOver和mouSEOut事件中获取从哪里移入和从哪里移出的DOM对象; Box.onmouSEOver = function(evt){ // 鼠标移入Box; alert(evt.relatedTarget); // 获取移入Box之前的那个元素; } Box.onmouSEOut = function(evt){ // 鼠标移出Box; alert(evt.relatedTarget); // 获取移出Box之后到的那个元素; }

// IE提供了两组与之对应的属性:fromElement和toElement;
// 兼容函数
function getEarget(evt){
var e = evt || window.event; // 得到事件对象;
if(e.srcElement){ // 如果支持srcElement,表示IE;
if(e.type == 'mouSEOver'){ // 如果是over事件;
return e.fromeElement; // 就使用from;
}else if(e.type == 'mouSEOut'){ // 如果是out;
return e.toElement; // 就使用to;
}
}else if(e.relatedTarget){ // 如果支持relatedTarget,表示W3C;
return e.relatedTarget;
}
}

2.阻止事件的默认行为

链接的默认行为就点击然后跳转到指定的页面; // 那么阻止默认行为就可以屏蔽跳转的这种操作,而实现自定义操作; // 取消事件默认行为还有一种不规范的做法,就是返回false; link.onclick = function(){ alert('Lee'); return false; // 直接返回false,就不会跳转了; } // PS:虽然return false;可以实现这个功能,但有漏洞; // 第一:代码必须写到最后,这样导致中间的代码执行后,有可能执行不到return false; // 第二:return false写到最前那么之后的自定义操作就失败了; // 解决方案:在最前面就阻止默认行为,并且后面还能执行代码; function preDef(evt){ // 跨浏览器兼容阻止默认行为; var e = evt || window.event; if(e.preventDefault){ e.preventDefault(); // W3C,阻止默认行为; }else{ e.returnValue = false; // IE,阻止默认行为; } }
菜单事件contextmenu // 当我们右击网页的时候,会自动出现windows自带菜单; // 那么我们可以使用contextmenu事件来修改我们指定的菜单;但前提是把右击的默认行为取消; addEvent(window,function(){ var text = docuemnt.getElementById('text'); addEvent(text,'contextmenu',function(evt){ // 添加右键菜单事件处理程序; var e = evt || window.event; preDef(e); // 阻止默认行为函数; var menu = document.getElementById('menu'); // 找到自定义的menu对象; menu.style.left = e.clientX+'px'; // 确定自定义menu在屏幕上的位置; menu.style.top = e.clientX+'px'; menu.style.visibility = 'visible'; // 设置自定义menu的属性为可见; addEvent(document,function(){ // 给document添加单击事件处理程序; docuemnt.getElementById('myMenu').style.visibility = 'hidden'; //将自定义的menu隐藏; }); }); });

4.卸载前事件beforeunload

提示;"离开"或"返回"操作; addEvent(window.'beforeunload',function(evt){ var evt = event || window.event; var message = '是否离开此页?'; evt.returnValue = message; return message; });

5.鼠标滚轮(mousewheel)和DOMMouseScroll

获取鼠标上下滚轮的距离; addEvent(docuemnt,'mousewheel',function(evt){ // 非Firefox; alert(getWD(evt)); }); addEvent(docuemnt,'DOMMouseScroll',function(evt){ // Firefox; alert(getWD(evt)); });

function getWD(evt){
var e = evt || window.event;
if(e.wheelDelta){ // mousewheel事件的滚动值保存在wheelDelta里;
return e.wheelDelta;
}else if(e.detail){ // DOMMouseScroll事件的滚动值保存在detail里;
return -evt.detail*30; // 保持计算的统一;
}
}

猜你在找的JavaScript相关文章