事件处理详解
分类:pc28.am

风流浪漫.关于获取事件目的

相近大家在JS中丰裕事件,是那样子的
view source  

前言

  本文大致收拾下绑定事件的两种办法,包容IE8- 的不二等秘书技(要是供给的话),事件委托,阻止传播,打消暗许行为,event对象等。

  在此之前做的多是手提式有线电话机端页面,监听事件也一向是 add伊夫ntListener ,今世浏览器基本都协助add伊芙ntListener ,除了万恶的IE8及更低版本IE。虽说不用太管IE8了(个人愚见),可是依然有须求整理下早先宽容性的管理方式

FF有一点点倔强,只协理arguments[0],不补助window.event。此番的确不怪IE,纵然把event作为window的性情不合标准,但大家都早就暗中认可那几个不是难点存在了,唯有FF这么经过了相当短的时间了也许匠心独具。所以,跨浏览器的平地风波目的拿到有以下三种办法:

1 obj.onclick=method
这种绑定事件的主意,宽容主流浏览器,但只要二个因素上增添多次如出生龙活虎辙事件呢?
view source  

HTML事件管理

  在HTML标签中平素给属性设置管理程序。HTML中步入了JS代码,因为供给作为、样式、布局抽离,这种形式今后生机勃勃度淘汰,就不长远索求了。

1 <button onclick="alert('HTML事件处理!')">点我</button>

 

getEvent : function{ return event ? event : window.event; //return event || window.event;//或者更简单的方式}

function getEvent() { return arguments[0] ? arguments[0] : window.event; //return arguments[0] || window.event;//或者更简单的方式}

1 obj.onclick=method1;
2 obj.onclick=method2;
3 obj.onclick=method3;
万一如此写,那么独有最后绑定的事件,这里是method3会被实行,当时我们就不能够用onclick那样的写法了,主角改登台了,在IE中大家能够应用attach伊夫nt方法
view source  

DOM0级事件管理

  通过成分对象的平地风波性质来绑定管理程序。先看栗子

<a href="http://www.baidu.com" class="a1">快点击我!</a>

    document.querySelector('.a1').onclick = function(){ //绑定事件
      alert('DOM0绑定--a');
    }

  先获得到成分a,在给成分的点击事件属性onclick绑定管理程序。

  这种方法的表征:

    1、轻巧易用,包容性优异,基本全体浏览器都帮助

    2、只可以绑定五个管理程序,重复绑定会覆盖。假设给a的onclick属性再绑定三个管理程序,那么今后的那些就能够被隐蔽掉

    3、只会在冒泡阶段触发

  撤除绑定也非常轻易,间接设为null就足以了。

    document.querySelector('.a1').onclick = null; //取消绑定

 

需求特别说美素佳儿种办法:HTML的DOM0级方式 带参的平地风波微电脑,如下:

1 //object.attachEvent(event,function);
2 btn1Obj.attachEvent("onclick",method1);
3 btn1Obj.attachEvent("onclick",method2);
4 btn1Obj.attachEvent("onclick",method3);
行使格式是前面是事件类型,注意的是索要加on,比方onclick,onsubmit,onchange,实践各种是
method3->method2->method1
心痛那几个微软的知心人方法,火狐和此外浏览器都不支持,幸运的是她们都援助W3C规范的add伊芙ntListener方法
view source  

DOM2级事件管理

  通过事件措施来绑定和平解决绑处理程序。同样看个栗子

<a href="http://www.baidu.com" class="a2">点击我!</a>

    document.querySelector('.a2').addEventListener('click', function(e){ //绑定事件1
      alert('DOM2绑定--a2 -- 1')
    }, false)

    document.querySelector('.a2').addEventListener('click', function(e){ //绑定事件2
      alert('DOM2绑定--a2 -- 2')
    }, false)

  addEventListener(eventName,listener,useCapture卡塔尔格局可感到事件绑定管理程序,第二个参数为事件类型(不带on);第一个参数是管理程序;第八个参数可钦命哪个阶段触发,false对应冒泡阶段、true对象捕获阶段(默许false),部分低版本浏览器供给那个参数不能够为空,所以最佳或然带上。

  这种办法的风味:

    1、可为同二个平地风波绑定多少个管理程序,会相继触发。数11次绑定同贰个管理程序,只会生效一次

    2、可钦定触发的级差,捕获阶段或许冒泡阶段

    3、包容IE8 - 之外的别样浏览器

  解绑的秘诀为:Element.removeEventListener(eventName,listener,useCapture卡塔尔;和绑定的用法风流浪漫致

  

  IE8- 有生龙活虎套本身的事件管理方法

    绑定:Element.attachEvent(eventNameWithOn,listener)

    解绑:Element.detachEvent(eventNameWithOn,listener)

    document.querySelector('.a2').attachEvent('onclick', function(e){
      alert('DOM2绑定--a2 -- 2')
    })

  特点:

pc28.am,   1、事件类型带on (eg:onclick卡塔尔(قطر‎

   2、只好在冒泡阶段触发

   3、IE10 - IE5都帮忙该措施

function handler{ //do something}按钮

1 //element.addEventListener(type,listener,useCapture);
2 btn1Obj.addEventListener("click",method1,false);
3 btn1Obj.addEventListener("click",method2,false);
4 btn1Obj.addEventListener("click",method3,false);
推行顺序为method1->method2->method3
做前端开拓程序猿,最正剧的某过于浏览器宽容难点了,上面有二种丰裕事件的点子,为了同生机勃勃增加事件的主意,我们只可以再重复写二个通用的拉长事件函数,万幸再有前人帮大家做了这事
view source  

宽容性管理方式

  三种情势的出入在事变类型和第八个参数,所以能够做一些拍卖,封装包容性管理的点子

    //通用方式
      //绑定
    function addEvent(targetElement,eventName,listener,useCapture){
      if(targetElement.addEventListener){ 
        targetElement.addEventListener(eventName,listener,useCapture);
      }else if(targetElement.attachEvent){
        targetElement.attachEvent('on'   eventName,listener);
      }else {
        targetElement['on'   eventName] = listener;
      }
    }
      //解绑
    function removeEvent(targetElement,eventName,listener,useCapture){
      if(targetElement.addEventListener){
        targetElement.removeEventListener(eventName,listener,useCapture);
      }else if(targetElement.attachEvent){
        targetElement.detachEvent('on'   eventName,listener);
      }else {
        targetElement['on'   eventName] = null;
      }
    }

  测量试验一下接受,在IE8及任何浏览器都足以健康使用。

    addEvent(document.querySelector('.a2'),'click',test,false)

    function test(e){

      alert('addEvent then removeEvent!');
      removeEvent(document.querySelector('.a2'),'click',test,false);  //取消绑定
    }

 

上面这种形式是全浏览器宽容的,但注重HTML的DOM0级形式的症结很显眼,所以未能成为像前三种那样的主流方式,而JS的DOM0级方式

01 function addEvent(elm, evType, fn, useCapture) {
02 if (elm.addEventListener) {
03 elm.addEventListener(evType, fn, useCapture);//DOM2.0
04 return true;
05 }
06 else if (elm.attachEvent) {
07 var r = elm.attachEvent(‘on‘ evType, fn);//IE5
08 return r;
09 }
10 else {
11 elm['on' evType] = fn;//DOM 0
12 }
13 }
下面是Dean Edwards 的版本
view source  

Event对象

  区别的诀要得到event对象的章程也不及

    attachEvent绑定: 通过 window.event获取event对象

    其余艺术(DOM0和add伊芙ntListener):管理函数字传送参直接拿走

    function test(e){ //兼容性的方式
      e = e || window.event;  //event对象
    }

  attachEvent绑定的办法,管理程序内部this指向window。想要获取成分对象 能够由此 window.event.srcElement

  其余办法的this指向触发成分 。 相符的也能够由此 event.target获取

      e = e || window.event;  //event对象
      var target = e.target || e.srcElement;  //触发对象

 

  • 带参的平地风波微处理器,如下:

    function handler{ //do something}btn.onclick = handler;//JS的DOM0级方式//btn.onclick = function{/do something/}//恐怕无名氏函数,效果同上

01 function addEvent(element, type, handler) {
02 //为每叁个事件管理函数分派二个唯朝气蓬勃的ID
03 if (!handler.$$guid) handler.$$guid = addEvent.guid ;
04 //为成分的平地风波类型创设一个哈希表
05 if (!element.events) element.events = {};
06 //为每贰个"成分/事件"对创制贰个事件管理程序的哈希表
07 var handlers = element.events[type];
08 if (!handlers) {
09 handlers = element.events[type] = {};
10 //存积攒在的事件处理函数(假如有卡塔尔(英语:State of Qatar)
11 if (element["on" type]) {
12 handlers[0] = element["on" type];
13 }
14 }
15 //将事件管理函数存入哈希表
16 handlers[handler.$$guid] = handler;
17 //指使一个大局的事件管理函数来做有所的行事
18 element["on" type] = handleEvent;
19 };
20 //用来创设唯风姿浪漫的ID的流量计
21 addEvent.guid = 1;
22 function removeEvent(element, type, handler) {
23 //从哈希表中删除事件管理函数 www.2cto.com
24 if (element.events && element.events[type]) {
25 delete element.events[type][handler.$$guid];
26 }
27 };
28 function handleEvent(event) {
29 var returnValue = true;
30 //抓获事件指标(IE使用全局事件指标卡塔尔
31 event = event || fixEvent(window.event);
32 //得到事件管理函数的哈希表的引用
33 var handlers = this.events[event.type];
34 //实践每两个管理函数
35 for (var i in handlers) {
36 this.$$handleEvent = handlers[i];
37 if (this.$$handleEvent(event) === false) {
38 returnValue = false;
39 }
40 }
41 return returnValue;
42 };
43 //为IE的事件目的加多一些“缺点和失误的”函数
44 function fixEvent(event) {
45 //增添标准的W3C方法
46 event.preventDefault = fixEvent.preventDefault;
47 event.stopPropagation = fixEvent.stopPropagation;
48 return event;
49 };
50 fixEvent.preventDefault = function() {
51 this.returnValue = false;
52 };
53 fixEvent.stopPropagation = function() {
54 this.cancelBubble = true;
55 };
功用特别勇敢,解决IE的this指向难题,event总是作为第叁个参数字传送入,跨浏览器就更不言自明。
聊到底贡献二个HTML5专门的学业组的本子:
view source  

阻挡传播和收回默许行为

  通过event对象的措施收回默许行为:

    event.preventDefault(卡塔尔    //其余浏览器

    event.returnValue = false //IE8-

  DOM0级绑定的 还足以直接 return false 来撤废暗中认可行为,全数浏览器都扶植

 

  event对象阻止传播:

    event.stopPropagation(卡塔尔 //其余浏览器

    event.cancelBubble = true //IE8 -

  日常能够如此写

      e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;  //阻止传播
      e.preventDefault ? e.preventDefault() : e.returnValue = false;    //取消默认行为

 

这种措施不是全浏览器包容的,[IE8-]不协助,IE9 未知,FF,Chrome扶助。从来感觉HTML的DOM0级事件管理和JS的DOM0级事件管理是等价的,现在做了过多试验才察觉双方是有分别的

01 var addEvent=(function(){
02 if(document.addEventListener){
03 return function(el,type,fn){
04 if(el.length){
05 for(var i=0;i<el.length;i ){
06 addEvent(el[i],type,fn);
07 }
08 }else{
09 el.addEventListener(type,fn,false);
10 }
11 };
12 }else{
13 return function(el,type,fn){
14 if(el.length){
15 for(var i=0;i<el.length;i ){
16 addEvent(el[i],type,fn);
17 }
18 }else{
19 el.attachEvent(‘on‘ type,function(){
20 return fn.call(el,window.event);
21 });
22 }
23 };
24 }
25 })();
莫不精心的读者开采了IE的attachEvent和W3C规范的addEventListener绑定多少个事件的实行顺序是不平等的

事件委托

  倘使多个因素的管理程序类同,若是每一个都绑定三回会很麻烦和失效,当时能够选择冒泡的原理(他们都会冒泡到父成分)直接在父成分上绑定事件。即为事件委托

    <section class="item item-3">
      <button class="btn1">点击我1!</button><button class="btn1">点击我2!</button><button class="btn1">点击我3!</button>
    </section>

  

    addEvent(document.querySelector('.item-3'),'click',function(e){
      e = e || window.event;  //event对象
      var target = e.target || e.srcElement;  //触发对象

      if(target.nodeName === 'BUTTON'){
        alert(target.innerText);
      }
    })

  本例中,想要完成点击开关输出按键文字。要是给八个按键分别绑定事件会不会太傻。所以一贯绑定了父成分,事件触发时,推断触发对象是不是是button标签,借使是,则输出文字。

 

二.关于获取事件源

 

event.srcElement是[IE8-]唯豆蔻梢头的主意,IE9 未知,此外浏览器都帮衬标准的event.target方式

摘自 你微笑时好美

三.关于阻止事件暗许行为

view source 1obj.onclick=method 这种绑定事件的点子,宽容主流浏览器,但假若三个要素上助长多次均等事件呢...

event.preventDefault(卡塔尔(قطر‎是明媒正娶方法,但[IE8-]不扶持,IE自身的方式是event.returnValue = false;

四.有关截止事件传播

event.stopPropagation(卡塔尔(英语:State of Qatar)是专门的学问措施,IE又有观念了,他要这么玩:event.cancelBubble

true;这里需求特别注意了,因为cancel是性质并非措施,与正规大相径庭,轻便记错

五.有关事件微机的丰盛和移除

ele.onclick = handler;ele.onclick=null;最古老的生龙活虎种方法

症结:同一事件只好绑定/解绑贰个平地风波微处理器

ele.add/removeEventListener(eventType, handler, catch);

和IE方式:ele.attach/detachEvent(‘on' eventType, handler);

优点:辅助绑定/解绑五个事件微处理器

缺欠:供给做宽容性判定。供给潜心的是:标准措施中最后五个参数表示是不是在事件捕获阶段绑定/解绑,IE不扶助事件捕获,所以也就从不第几个参数了

在乎:IE格局不但方法名与标准分裂,参数中事件类型还要加上on,不然绑定无效但不报错

六.跨浏览器的事件管理

//跨浏览器的事件处理器添加方式var EventUtil = { addHandler : function{ if(elem.addEventListener){ elem.addEventListener; } else if{ elem.attachEvent;//添加多个同一类型的handler时,IE方式的规则是最后添加的最先触发 } else{ if(typeof elem["on"   type] === 'function'){ var oldHandler = elem["on"   type]; elem["on"   type] = function; handler(); } } else{ elem["on"   type] = handler;//支持添加多个事件处理器 } } }, getEvent : function{ return event ? event : window.event; }, getTarget : function{ return event.target || event.srcElement; }, preventDefault : function{ if{ event.preventDefault(); } else{ event.returnValue = false; } }, removeHandler : function{ if(elem.removeEventListener){ elem.removeEventListener; } else if{ elem.detachEvent; } else{ elem["on"   type] = null;//不支持移除单一事件处理器,只能全部移除 } }, stopPropagation : function{ if(event.stopPropagation){ event.stopPropagation(); } else{ event.cancelBubble = true; } }, getRelatedTarget : function{ if{ return event.relatedTarget; } else if(event.toElement && event.type == "mouseout"){ return event.toElement; } else if(event.fromElement && event.type == "mouseover"){ return event.fromElement; } else{ return null; } }, /*IE8点击左键和中键都是0;FF无法识别中键;Chrome正常*/ getButton : function{//返回0,1,2 - 左,中,右 if(document.implementation.hasFeature){ return event.button; } else{ switch{ case 0:case 1:case 3:case 5:case 7: return 0; break; case 2:case 6: return 2; break; case 4: return 1; break; default: break; } } }, /*只能检测keypress事件,返回值等于将要显示的字符编码*/ /*IE和Chrome只有能显示的字符键才触发,FF其它键也能触发,返回值为0*/ getCharCode : function{ if(typeof event.charCode == "number"){ return event.charCode; } else{ return event.keyCode; } }};

总结示范

只重要项目目中向来不选用诸如 jQuery 之类的库,怎么样方便地为成分绑定事件,并合营各类浏览器呢?下边那一个轻易的 Utility 应该可以思虑。

var eventUtility = { addEvent : function { if(typeof addEventListener !== "undefined") { el.addEventListener; } else if(typeof attachEvent !== "undefined") { el.attachEvent; } else { el["on"   type] = fn; } }, removeEvent : function { if(typeof removeEventListener !== "undefined") { el.removeEventListener; } else if(typeof detachEvent !== "undefined") { el.detachEvent; } else { el["on"   type] = null; } }, getTarget : function { if(typeof event.target !== "undefined") { return event.target; } else { return event.srcElement; } }, preventDefault : function { if(typeof event.preventDefault !== "undefined") { event.preventDefault(); } else { event.returnValue = false; } }};

var eventHandler = function { var target = eventUtility.getTarget, tagName = target.tagName; if { if(tagName === "A" || tagName === "BUTTON") { alert("You clicked on an A element, and the innerHTML is "   target.innerHTML   "!"); eventUtility.preventDefault; } } else if(evt.type === "mouseover" && tagName === "A") { alert("mouseovered "   target.innerHTML); }};eventUtility.addEvent(document, "click", eventHandler);eventUtility.addEvent(document, "mouseover", eventHandler);eventUtility.removeEvent(document, "mouseover", eventHandler);

本文由pc28.am发布于pc28.am,转载请注明出处:事件处理详解

上一篇:PHP实现动态数字展示特效,基于jQuery实现动态数 下一篇:没有了
猜你喜欢
热门排行
精彩图文