js事件详解(2)事件对象

在触发DOM上的某个事件时,会产生一个时间对象event,该对象包含着所有与事件有关的信息。

所有的浏览器都支持event对象,但支持的方式不同。

一、DOM中的事件对象

兼容DOM的浏览器会将一个event对象传到事件处理程序中,而无论指定事件处理程序使用的是什么方法。
var btn = doucument.getElementById('myBtn');
btn.onclick = function(event){
    alert(event.type);//'click'
}

btn.addEventListener('click',function(){
    alert(event.type);//'click'
},false);

<input type="button" value="Click Me" onclick="alert(event.type)"/> 

event对象的属性/方法

  • bubbles Boolean 只读 表明事件是否冒泡
  • cancelable Boolean 只读 表明是否可以取消事件的默认行为
  • currentTarget Element 只读 其事件处理程序当前正在处理事件的那个元素
  • defaultPrevented Boolean 只读
    为true表示已经调用了preventDefault()(DOM3级事件中新增)
  • detail Integer 只读 与事件相关的细节信息
  • eventPhase Integer 只读 调用事件处理程序的阶段:1表示捕获阶段,2表示“处于目标”,3表示冒泡阶段
  • preventDefault() Function 只读 取消事件的默认行为。如果cancelable是true,则可以使用这个方法
  • stopImmediatePropagation() Function 只读
    取消事件的进一步捕获或冒泡,同时阻止任何事件处理程序被调用(DOM3级事件中新增)
  • stopPropagation() Function 只读
    取消事件的进一步捕获或冒泡。如果bubbles为true,则可以使用这个方法
  • target Element 只读 事件的目标
  • trusted Boolean 只读
    为true表示事件是浏览器生成的。为false表示事件是由开发人员通过JavaScript创建的(DOM3级事件中新增)
  • type String 只读 被触发的事件的类型
  • view AbstractView 只读 与事件关联的抽象视图。等同于发生事件的window对象

在事件处理程序内部,this始终等于currentTarget的值,而target则只包含事件的实际目标。

var btn = doucument.getElementById('myBtn');
btn.onclick = function(event){
    alert(event.currentTarget===this);//true
    alert(event.target===this);//true
}

但是,如果dom中存在层级关系时:

doucument.body.onclick = function(event){
    alert(event.currentTarget===doucument.body);//true
    alert(this===doucument.body);//true
    alert(event.target===doucument.getElementById('myBtn'));
}

当单击这个例子中的按钮时,this和currentTarget都等于document.body,因为事件处理程序是注册到这个元素上的。然而,target元素却等于按钮元素,因为它是click事件真正的目标。由于按钮上并没有注册事件处理程序,结果click事件就冒泡到了document.body,在那里事件才得到了处理。

当需要通过一个事件处理程序处理多个事件时,可以通过event对象的type属性:

var btn = document.getElementById("myBtn"); 
var handler = function(event){ 

    switch(event.type){ 
        case "click": 
            alert("Clicked"); 
            break; 
        case "mouseover": 
            event.target.style.backgroundColor = "red"; 
            break; 
        case "mouseout": 
            event.target.style.backgroundColor = ""; 
            break; 
    } 
}; 
btn.onclick = handler; 
btn.onmouseover = handler; 
btn.onmouseout = handler;

要阻止特定事件的默认行为,可以使用preventDefault()方法。

例如:取消超点击链接的跳转操作。

var link = document.getElementById("myLink"); 
    link.onclick = function(event){ 
    event.preventDefault(); 
}; 

只有cancelable属性设置为true的事件,才可以使用preventDefault()来取消其默认行为。

stopPropagation()方法用于立即停止事件在DOM层次中的传播,即取消进一步的事件捕获或冒泡。

例如,直接添加到一个按钮的事件处理程序可以调用stopPropagation(),从而避免触发注册在document.body上面的事件处理程序,

var btn = document.getElementById("myBtn"); 
btn.onclick = function(event){ 
    alert("Clicked"); 
    event.stopPropagation(); //阻止事件冒泡,所以只会弹出当前的对话框。
}; 

document.body.onclick = function(event){ 
    alert("Body clicked"); 
}; 

事件对象的eventPhase属性,可以用来确定事件当前正位于事件流的哪个阶段。

eventPhase=1,在捕获阶段调用的事件处理程序
eventPhase=2,事件处理程序处于目标对象上
eventPhase=3,在冒泡阶段调用的事件处理程序

尽管“处于目标”发生在冒泡阶段,但eventPhase仍然一直等于2

var btn = document.getElementById("myBtn"); 
btn.onclick = function(event){ 
    alert(event.eventPhase); //2 ,当eventPhase等于2时,this、target和currentTarget始终都是相等的
}; 
document.body.addEventListener("click", function(event){ 
    alert(event.eventPhase); //1 
}, true); 
document.body.onclick = function(event){ 
    alert(event.eventPhase); //3 
}; 

只有在事件处理程序执行期间,event对象才会存在;一旦事件处理程序执行完成,event对象就会被销毁。

二、IE中的事件对象

DOM中的事件对象是传递到事件处理程序中的,所以在事件处理程序中直接通过event对象就可以访问。

而IE中的事件处理的访问形式,取决于添加事件处理程序的方法。

1.当使用DOM0级方法添加事件处理程序时,event对象作为window对象的一个属性存在

var btn = document.getElementById('myBtn');
btn.onclick = function(){
    var event = window.event;
    alert(event.type);//'click'
}

2.当使用attachEvent方法添加事件处理程序,会有一个event对象作为参数被传入事件处理程序的函数中。

var btn = document.getElementById("myBtn"); 
btn.attachEvent("onclick", function(event){ 
    alert(event.type); //"click" 
});

在像这样使用attachEvent()的情况下,也可以通过window对象来访问event对象,就像使用DOM0级方法时一样。不过为方便起见,同一个对象也会作为参数传递。

3.通过HTML特性指定事件处理程序

与访问DOM的event对象方式一样。

<input type="button" value="Click Me" onclick="alert(event.type)"> 

IE中事件对象的属性/方法:

  • cancelBubble Boolean 读/写
    默认值为false,但将其设置为true就可以取消事件冒泡(与DOM中的stopPropagation()方法的作用相同)
  • returnValue Boolean 读/写
    默认值为true,但将其设置为false就可以取消事件的默认行为(与DOM中的preventDefault()方法的作用相同)
  • srcElement Element 只读 事件的目标(与DOM中的target属性相同)
  • type String 只读 被触发的事件的类型

因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为this会始终等于事件目标。故而,最好还是使用event.srcElement比较保险。

var btn = document.getElementById("myBtn"); 
btn.onclick = function(){ //DOM0级方法指定事件处理程序
    alert(window.event.srcElement === this); //true 
}; 
btn.attachEvent("onclick", function(event){ 
    alert(event.srcElement === this); //false 
}); 


returnValue属性相当于DOM中的preventDefault()方法,它们的作用都是取消给定事件的默认行为。只要将returnValue设置为false,就可以阻止默认行为。

var link = document.getElementById("myLink"); 
link.onclick = function(){ 
    window.event.returnValue = false; //与DOM不同的是,在此没有办法确定事件是否能被取消。
};

cancelBubble属性与DOM中的stopPropagation()方法作用相同,都是用来停止事件冒泡的。由于IE不支持事件捕获,因而只能取消事件冒泡;但stopPropagatioin()可以同时取消事件捕获和冒泡。

var btn = document.getElementById("myBtn"); 
btn.onclick = function(){ 
    alert("Clicked"); 
    window.event.cancelBubble = true; 
}; 
document.body.onclick = function(){ 
    alert("Body clicked"); //被阻止弹出
}; 

三、跨浏览器的事件对象

虽然DOM和IE中的event对象不同,但基于它们之间的相似性依旧可以拿出跨浏览器的方案来。

我们在前面的EventUtil对象上加以改造。

var EventUtil = { 
    addHandler: function(element, type, handler){ 
        //省略的代码
    }, 

    getEvent: function(event){ 
        return event ? event : window.event; 
    }, 

    getTarget: function(event){ 
        return event.target || event.srcElement; 
    }, 

    preventDefault: function(event){ 
        if (event.preventDefault){ 
            event.preventDefault(); 
        } else { 
            event.returnValue = false; 
        } 
    }, 

    removeHandler: function(element, type, handler){ 
        //省略的代码
    }, 

    stopPropagation: function(event){ //由于IE不支持事件捕获,因此这个方法在跨浏览器的情况下,也只能用来阻止事件冒泡。
        if (event.stopPropagation){ 
            event.stopPropagation(); 
        } else { 
            event.cancelBubble = true; 
        } 
    } 
}; 

在使用这个方法时,必须假设有一个事件对象传入到事件处理程序中,而且要把该变量传给这个方法

btn.onclick = function(event){ 
    event = EventUtil.getEvent(event); 
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值