指定事件处理程序的几种方式

通过指定事件处理程序可以侦听事件的发生并对其作出响应,已达到某种交互目的。那么指定事件处理程序的方式有哪些呢?

比如有以下代码:

<input id="btn" type="button" value="click me" />

要求为按钮指定一个单击事件处理程序,即单击按钮时输出相应信息。

1.HTML事件处理程序

某个元素支持的每种事件,都可以使用一个与相应事件处理程序同名的HTML特性来指定。特性的值可以是能够执行的js代码。

<input id="btn" value="click me" onclick="alert('clicked')" />

也可以调用在页面其他地方定义的脚本。

<script type="text/javascript"> 
  function showMessage(){
   alert("clicked");
} </script>

<
input id="btn" value="click me" onclick="showMessage()" />

showMessage()这个函数可以向以上方式定义,也可以被包含在一个外部文件中。事件处理程序中的代码在执行时,有权访问全局作用域中的任何代码。

缺点:

  • 时差问题:因为需要触发事件处理程序时条件不具备。解决方法是将HTML事件处理程序封装在一个try-catch块中,以便错误不浮出水面。
<input type="button" value="click me" onclick="try{showMessage();}catch(ex){}"/>
  • 作用域链:由于不同浏览器的JavaScript引擎遵循的标识符解析规则裸游差异,可能会导致扩展事件处理程序的作用域链有不同结果。
  • HTML与JavaScript代码紧密耦合:如果想要更换事件处理程序,需要同时修改两个地方。

2.DOM0级事件处理程序

通过JavaScript指定处理程序的传统方式,将一个函数赋值给一个事件处理程序属性。每个元素(包括document和window)都有自己的事件处理程序属性,这些属性通常全部小写,如onclick。

var btn = document.getElementById("btn");
//指定事件处理程序
btn.onclick = function(){
   alert("Clicked"); 
};

//想要取消事件处理程序的话,只需将事件处理程序属性设为null即可
btn.onclick = null;

这种方式下指定的事件处理程序被认为是元素的方法,所以其作用域为元素的作用域。即程序中的this引用当前元素。如:

btn.οnclick=function(){
  alert(this.id);//btn
}

另外以这种方式添加的事件处理程序会在事件流的冒泡阶段被处理

3.DOM2级事件处理程序

“DOM2级事件”定义了两个方法,用于处理指定和删除事件处理程序的操作:addEventListener()和removeEventListener()。所有的DOM节点都包含着两个方法,并且它们都接受三个参数:要处理的事件名、事件处理程序的函数和一个布尔值。其中布尔值为true表示在捕获阶段调用事件处理程序,为false表示在冒泡阶段调用事件处理程序。

//指定事件处理程序 
btn.addEventListener("click",fucntion(){alert("clicked");},false);
//取消事件处理程序
btn.removeEventListener("click",function(){alert("clicked");},false);//无效
//指定和取消的参数必须完全相同才有效。而匿名函数是两个不同的函数,所以无效
//所以为了能够取消,最好函数采用命名函数
var handler = function(){
   alert("clicked"); 
};
//添加事件处理程序
btn.addEventListener("click",handler,false);
//取消事件处理程序
btn.removeEventListener("click",handler,false);//有效

作用域与DOM0级事件指定事件处理程序的作用域相同,也是元素的作用域。但与DOM0不同的是,DOM2可以指定多个事件处理程序
事件处理程序的触发顺序是按照添加事件处理程序的顺序来的。

支持DOM2级事件处理程序的浏览器有IE9+、Firefox、Safari、Chrome和Opera。

4.IE事件处理程序

IE实现了与DOM类似的两种方法:attachEvent()和detachEvent()。接受两个参数:事件处理程序名与事件处理程序函数。IE8-只支持事件冒泡,所以通过attachEvent()添加的事件处理程序被添加到事件冒泡阶段。

//添加事件处理程序
btn.attachEvent("onclick",handler);
//取消事件处理程序
btn.detachEvent("onclick",handler);
//取消参数必须与添加完全相同,所以事件处理程序函数(同DOM2级事件中的分析一样)不要是匿名函数。

IE事件处理程序与DOM事件处理程序的最大区别:DOM0/2级事件处理程序的作用域是元素作用域;而IE事件处理程序是全局作用域,即this等于widow。

IE也可以指定多个事件处理程序,我运行了相关代码发现:触发顺序同添加顺序(IE9);而《JavaScript高级程序设计》中说触发顺序应该同添加顺序相反。到底是哪个,暂时不清楚。。

支持IE事件处理程序的浏览器有IE和Opera。

5.跨浏览器的事件处理程序

        //跨浏览器的事件处理程序 恰当的使用能力检测即可实现 
        //要保证事件的代码能在大多数浏览器下一致地运行,只需关注冒泡阶段
        //第一个要创建的方法是addHandler(),职责是视情况分别使用DOM0级方法、DOM2级方法
        //或IE方法来添加事件。这个方法属于一个名叫EventUtil的对象。
        //接受三个参数:要操作的元素、事件名称和事件处理程序函数
        //removeHandler() 也接受相同的参数。职责是移除之前添加的事件处理程序-无论该事件采取什么方式添加到元素中的,如果其他方法无效,默认采用DOM0级方法
        
        var EventUtil = {
            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.detachEvent){
                    element.detachEvent("on"+type,handler);
                }else{
                    element["on"+type] = null;
                }
            }
        
        };
        var handler = function(){
            alert("Clicked");
        };
        //指定
        EventUtil.addHandler(btn,"click",handler);
        //移除事件处理程序
        EventUtil.removeHandler(btn,"click",handler);
        
        //注意 以上的addHandler()和removeHandler()没有考虑到所有的浏览器问题,例如IE中的作用域问题
        //不过,使用它们添加和移除事件处理程序还是足够了。此外还要注意,DOM0级对每个事件支持一个事件处理程序。
        //好在,只支持DOM0级的浏览器已经没那么多了。

 

转载于:https://www.cnblogs.com/huangyx/p/4761624.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值