// 事件绑定分为两种:

// 一种是传统事件绑定(内联模型/脚本模型);上一章内容;

// 一种是现代事件绑定(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传递到切换器里;
}
 // 综上三个问题:覆盖问题/可读性问题/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,'load',function(){
var box = document.getElementById('box');
addEvent(box,'click',toBlue);
});
function toRed(){
this.className = 'red';
addEvent(this,'click',toBlue);
}
function toBlue(){
this.className = 'blue';
addEvent(this,'click',toRed);

二 W3C事件处理函数

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

 // 所有DOM节点中都包含这两个方法,并且它们都接收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',init,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',toBlue,false); // 添加需要切换的事件处理函数;
} function toBlue(){
this.className = 'blue';
this.removeEventListener('click',toBlue,false);
this.addEventListener('click',toRed,false);
} // 设置冒泡和捕获阶段
document.addEventListener('click',function(){
alert('document');
},true); // 设置为捕获; document.addEventListener('click',function(){
alert('Lee');
},false); // 设置为冒泡;

三 IE事件处理函数

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

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

 // 在使用这两组函数的时候,区别:
// 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,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);
}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;
}
}

四 事件对象补充

 1.relatedTarget
// 这个属性可以在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,阻止默认行为;
}
}
 3.上下文菜单事件contextmenu
// 当我们右击网页的时候,会自动出现windows自带的菜单;
// 那么我们可以使用contextmenu事件来修改我们指定的菜单;但前提是把右击的默认行为取消;
addEvent(window,'load',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,'click',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--事件绑定及深入(26)的更多相关文章

  1. 第一百二十一节,JavaScript事件绑定及深入

    JavaScript事件绑定及深入 学习要点: 1.传统事件绑定的问题 2.W3C事件处理函数 3.IE事件处理函数 4.事件对象的其他补充 事件绑定分为两种:一种是传统事件绑定(内联模型,脚本模型) ...

  2. JavaScript事件绑定的三种方式

    (一)事件绑定的三种方式 (1)通过on的形式 <script type="text/javascript"> var div = document.getElemen ...

  3. Javascript事件绑定的几种方式

    Javascript的事件绑定主要有四种方法(一下在IE中运行正常,但不保证其他浏览器): [注:onXXX为某一事件,fun为某一function,domId为某一DOM对象id,event类型见后 ...

  4. Javascript事件模型(三):JavaScript事件绑定方法总结(及Jquery)

    JavaScript中绑定事件的方法主要有三种: 1 在DOM元素中直接绑定 2 JavaScript代码中直接绑定 3 绑定事件监听函数 JQuery中绑定事件的几种方法 主要有on().bind( ...

  5. javaScript事件绑定

    事件绑定,就是要对某一个东西进行操作.(因为你想让他实现什么效果,所以就得绑定他,哈哈哈!) 要想让 JavaScript 对用户的操作作出响应,首先要对 DOM 元素绑定事件处理函数.所谓事件处理函 ...

  6. 详解javascript事件绑定使用方法

    由于html是从上至下加载的,通常我们如果在head部分引入javascript文件,那么我们都会在javascript的开头添加window.onload事件,防止在文档问加载完成时进行DOM操作所 ...

  7. javascript事件绑定和普通事件的区别

    <!doctype html><html lang="en"><head> <meta charset="UTF-8" ...

  8. javascript 事件绑定

    一.最简单和向后兼容性最好的事件绑定方法是把事件绑定到元素标识的属性.事件属性名称由事件类型外加一个“on”前缀构成.这些属性也被称为事件处理器 <INPUT TYPE="text&q ...

  9. javascript事件绑定1-模拟jquery可爱的东西

    1.给对象添加事件attachEvent(兼容IE,不兼容ff.chrome) <html xmlns="http://www.w3.org/1999/xhtml"> ...

  10. JavaScript事件绑定的常见方式

    在Javascript中,事件绑定一共有3种方式: ① 行内绑定 ② 动态绑定 ③ 事件监听 原文: https://mbd.baidu.com/newspage/data/landingsuper? ...

随机推荐

  1. 一个简单文本分类任务-EM算法-R语言

    一.问题介绍 概率分布模型中,有时只含有可观测变量,如单硬币投掷模型,对于每个测试样例,硬币最终是正面还是反面是可以观测的.而有时还含有不可观测变量,如三硬币投掷模型.问题这样描述,首先投掷硬币A,如 ...

  2. Linux巩固记录(8) Hbase shell 基本使用

    继续前几篇内容,讲解hbase基本使用 1.进入hbase shell: hbase有很多种操作方式,比如shell,java客户端,webUI等,可以直接输入hbase进行提示 [root@mast ...

  3. webApp开发中的总结

    meta标签:  H5页面窗口自动调整到设备宽度,并禁止用户缩放页面 <meta name="viewport" content="width=device-wid ...

  4. job任务执行流程与分区机制

    job任务执行流程    1.run job阶段        ①收集整个job的环境信息(比如通过conf设定的参数,还有mapperClass,reducerClass,以及输出kv类型)     ...

  5. C#枚举中使用Flags特性

    .NET中的枚举我们一般有两种用法,一是表示唯一的元素序列:还有就是用来表示多种复合的状态.这个时候一般需要为枚举加上[Flags]特性标记为位域,这样我们就可以用"或"运算符组合 ...

  6. 架构模式数据源模式之:数据映射器(Data Mapper)

    一:数据映射器 关系型数据库用来存储数据和关系,对象则可以处理业务逻辑,所以,要把数据本身和业务逻辑糅杂到一个对象中,我们要么使用 活动记录,要么把两者分开,通过数据映射器把两者关联起来. 数据映射器 ...

  7. 静态编译 Qt5.7.0 (含 openssl 支持)

    关于Qt静态便宜的环境等,请先参见 Win10 + VS2015 下编译 Qt5.6.0 . 首先编译 openssl .我这里用的版本是 openssl 1.0.2j (新的1.1版本的便宜稍有不同 ...

  8. 如何让你的网站用上免费的HTTPS

    因为之前网站上被注入了广告,再百般尝试之后最后还是使用了HTTPS解决了. 在实现HTTPS的时候最关键的就是证书. 证书的质量觉得了你被多少浏览器所信任. 证书的价格也就蹭蹭蹭往上涨了. 这里推荐一 ...

  9. java-jmx使用

    先粘一段内容 .程序初哥一般是写死在程序中,到要改变的时候就去修改代码,然后重新编译发布. .程序熟手则配置在文件中(JAVA一般都是properties文件),到要改变的时候只要修改配置文件,但还是 ...

  10. Nginx缓存配置之手动清除缓存

    访问我的博客 前言 前文介绍了利用 nginx 的 nginx_ngx_cache_purge 模块来实现缓存功能,并设置了缓存时间为一天. 但是如果前端修改了页面,比如首页,由于 Nginx 缓存的 ...