事件处理程序

事件就是用户或浏览器自身执行的某种动作,例如click、load等,都是事件的名字,响应事件的函数叫做事件处理程序,事件处理程序的名字以“on”开头,例如click事件的事件处理程序就是onload。

HTML事件处理程序

每个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。例如:要让按钮被单击时执行一些javascript,代码如下:

<script type="text/javascript">
      function showMessage(){
          alert("hello world!");
      }
<input type="button" value="Click Me" onclick="showMessage()" />

showMessage()函数是在一个独立的<script>元素中定义的,也可以包含在一个外部文件中,这样做有一些特点:

  • 独到之处
  1. 会创建一个封装着元素属性值的函数,这个函数中有一个局部变量event(事件对象)
  2. 在这个函数内部,this值等于事件的目标元素
  • 问题
  1. 存在时差问题
  2. 这样扩展事件处理程序的作用域链在不同的浏览器会导致不同结果
  3. HTML与javascript代码紧密耦合,如果要更换事件处理程序,则要改动HTML代码和javascript代码两个部分(因为js代码和元素是对应的),所以开发人员从HTML事件处理程序转向使用Javascript指定事件处理程序。

DOM0级事件处理程序

通过JavaScript指定事件处理程序的传统方法,就是将一个函数赋值给一个事件处理程序属性。

  • 每个元素(包括window和document)都有自己的事件处理程序属性,这些属性通常全部小写,如onclick。将这种属性的值设为一个函数,就可以指定事件处理程序。
 var btn=document.getElementById("myBtn");
         btn.onclick=function(){
            alert("Clicked");
         };

注意:在这些代码运行前不会指定事件处理程序,因为如果这些代码在页面中位于按钮后面,就有可能在一段时间内怎么点击都没有反应。

  • 使用DOM0级方法指定的事件处理程序被认为是元素的方法。因此,这时候的事件处理程序是在元素的作用域中运行;换句话说,程序的this引用当前元素。可以在事件处理程序中通过this访问元素的任何属性和方法。
 var btn=document.getElementById("myBtn");
       btn.onclick=function(){
             alert(this.id);//"myBtn"
       };

注意:这种方式添加的事件处理程序会在事件流的冒泡阶段被处理。

  • 可以删除通过DOM0级方法指定的事件处理程序: btn.onclick=null; //删除事件处理程序
    如果使用的是HTML指定时间处理程序,那么onclick属性的值就是一个包含着在同名HTML特性中指定的代码的函数。将相应的属性设为null,也可以删除以这种方式指定的事件处理程序。

DOM2级事件处理程序

DOM2级事件定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()removeEventListener()。所有DOM节点都包含这两个方法,并且他们都接受3个参数。要处理的事件名、作为事件处理程序的函数和一个布尔值。布尔值中true表示在捕获阶段调用事件处理程序;false表示在冒泡阶段调用事件处理程序。如果不是特别需要,不建议在事件捕获阶段注册事件处理程序。

  • 用DOM2级方法添加事件处理程序的好处是可以添加多个事件处理程序:
    var btn=document.getElementById("myBtn");
            btn.addEventListener("click",function(){
                alert(this.id);
            },false);
            btn.addEventListener("click",function(){
                alert("Hello world!");
            },false);

这两个事件处理程序会按照添加它们的顺序触发

  • 通过addEventListener()添加的事件处理程序只能通过removeEventListener()方法移除。移除时传入的参数与添加时传入的参数要相同。这也意味着通过addEventListener()添加的匿名函数无法移除。
    var btn=document.getElementById("myBtn");
            btn.addEventListener("click",function(){
                alert(this.id);
            },false);
            btn.removeEventListener("click",function(){
                alert(this.id);
            },false);//没有用!看似传入了相同的参数,其实这里的第二个参数与addEventListener()中的第二个参数是完全不同的函数

因此应该像下面这种写法:

    var btn=document.getElementById("myBtn");
           var handler=function(){
               alert(this.id);
           };
            btn.addEventListener("click",handler,false);
            btn.removeEventListener("click",handler,false);

IE事件处理程序

IE实现了与DOM中类似的两个方法:attachEvent()和detachEvent()。这两个方法接收相同的两个参数:事件处理程序名称和事件处理程序函数。由于IE8及更早版本只支持事件冒泡,所以通过attachEvent()添加的事件处理程序都会被添加到冒泡阶段。

     var btn=document.getElementById("myBtn");
            btn.attachEvent("onclick",function(){   //是onclick,而非addEventListener()的click
                 alert(this.id);
             });
  • 在IE中使用attachEvent()与使用DOM0级方法的主要区别是事件处理程序的作用域。DOM0中是在元素的作用域内运行;在attachEvent()中是在全局作用域内运行,因此this=window。
    1 var btn=document.getElementById("myBtn");
    2         btn.attachEvent("onclick",function(){
    3              alert(this===window);  //true
    4          });
  • 与addEventListener()类似,attachEvent()也可以用来为一个元素添加多个事件处理程序。不同的是attachEvent()不是以添加事件的顺序执行,而是以相反的顺序执行。
  • 同样的用attachEvent()添加的事件如果是匿名函数则不能移除,否则可以用detachEvent()方法移除。

跨浏览器的事件处理程序

使用能力检测来隔离浏览器的差异。要保证处理事件的代码能在大多数浏览器下一致的运行,只需关注冒泡阶段。

    var EventUtil={
       //视情况分别使用DOM0级方法、DOM2级方法、IE方法来添加/删除事件,需要3个参数:
        要操作的元素、事件名称、事件处理程序函数。
            addHandler:function(element,type,handler){
                if(element.addEventListener){
                    element.addEventListener(type,handler,false);
                } else if(element.attachEvent){
                    element.attachEvent("on"+type,handler);
                } else{
                    element["on"+type]=handler;
                }
            },
            removeHandler:function(element,type,handler){
                if(element.removeEventListener){
                    element.removeEventListener(type,handler,false);
                } else if(element.detchaEvent){
                    element.detchaEvent("on"+type,handler);
                } else{
                    element["on"+type]=null;
                }
            }
        };

可以用像如下代码这样使用以上两个方法:

    var btn=document.getElementById("myBtn");
        var handler=function(){
            alert("Clicked");
        };
        EventUtil.addHandler(btn,click,handler);
        //其他代码
        EventUtil.removeHandler(btn,click,handler);

addHandler()和removeHandler()没有考虑到所有的浏览器问题,例如IE中的作用域问题。不过,使用它们添加和移除事件处理程序还是足够了。此外还要注意,DOM0级对每个事件只支持一个事件处理。好在支持DOM0级的浏览器已经不多了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容

  • 1、事件就是用户或浏览器自身执行的某种动作。2、事件处理程序(或事件监听器)就是响应某个事件的函数。 HTML事件...
    Wonder233阅读 179评论 0 0
  • 一、事件流 1.1 事件流 事件流:从页面中接受事件的顺序 事件冒泡:即事件开始时由最具体的元素(文档中嵌套层次最...
    范小饭_阅读 1,070评论 1 9
  • ** 定义:**事件:用户或浏览器自身执行的某种动作。事件流:描述的是从页面中接收事件的顺序,也可理解为事件在页面...
    zouyang0921阅读 580评论 0 0
  • 简单理解事件是用户或浏览器自身执行的某种动作。诸如click、load而事件处理程序则是响应某个事件的函数。诸如o...
    Miss____Du阅读 821评论 7 6
  • 今天看了《交办的艺术》,里面讲到将任务交给部下就要全全相信他,不要干涉,这样才利于进步所要做的就是给他舒适的环境就...
    阿光Jason阅读 163评论 0 1