JavaScript 事件

 

 

“事件是把所有东西粘在一起的胶水”,没有事件就没有JavaScript强大的交互作用。

 

 

基本认识

 

1.JavaScript是完全异步的。这就意味着你不必去处理那些烦人的多线程问题,可以轻松监听及响应各种事件。

 

2.对于事件的处理我们只需要使用事件处理函数简单地注册一个回调函数,当事件触发时,回调函数将会被调用执行。

 

// 定义回调函数loaded
function  loaded() {
    alert(
' Finished! ' );
}
// 注册回调函数
window.onload  =  loaded;

 

3.事件的两个阶段:捕获和冒泡。或许你和我一样,在相当长时间内并没有注意到这两个概念。

 

以下是一段简单的HTML模型:

 

< body >
    
< div >
        
< ul >
            
< li >
                点击此处
            
</ li >
        
</ ul >
    
</ div >
</ body >

 

现在我们看看浏览器是怎样“捕获”和“冒泡”的。

 

假如我们在li中发生了点击(clikc)事件,body元素会首先“捕获”到事件,如果我们为点击事件设置了事件处理函数,这时候会执行事件处理函数。接着依次是div、ul、li,“捕获”并响应事件。这时事件从“捕获”阶段进入了“冒泡”阶段,li、ul、div、body依次又执行了他们相应的事件处理函数。实际上,你可以为“捕获”和“冒泡”阶段分别绑定不同的函数。

 

这时候你不要急着用onclick = function(){...}这种方法去尝试这样的机制,因为它只支持冒泡机制而忽略了捕获过程。更为重要的是,不管你用什么方式去注册一个事件处理程序,IE只工作在冒泡阶段,也就是说IE并不支持捕获机制。

 

=========================================================================

 

 

在写接下来的内容之前先F一下微软这个混蛋成天搞特殊,IE的事件对象的实现和W3C标准是不一样的,所以我们总是要在我们的函数中处理这样的差异。以下代码可以消除这样的一种差异:

//  e为函数参数中传入的事件对象
=  e  ||  window.event;

 

 

废话少说,马上进入正题!(以下代码绝大部分来自于《精通JavaScript》)

 

 

阻止事件冒泡

 

刚才跟大家看到了JavaScript冒泡的机制,但在某些情况下,你可能不想让事件响应出现这样的情况。我们有办法阻止这样的情况发生。

 

以下是一段阻止冒泡的通用代码

 

function  stopBubble(e) {
    
//  如果传入了事件对象,那么就是非IE浏览器
     if  (e  &&  e.stopPropagation)
        
//  支持W3C的stopPropation()方法
        e.stopPropagation();
    
else
        
//  否则,我们得使用IE的方式来取消事件冒泡
        window.event.cancelBubble  =   true ;
}

 

应用举例

 

< div id = " divTag " >
    
< ul id = " ulTag " >
        
< li id = " liTag " >
            点击此处
        
< / li>
     < / ul>
< / div>

< script type = " text/javascript " >

//  分别获取三个元素
=  document.getElementById( ' liTag ' );
=  document.getElementById( ' ulTag ' );
=  document.getElementById( ' divTag ' );

//  为三个元素注册点击响应函数
ExpandedBlockStart.gifContractedBlock.gif
l.onclick  =   function  (e)  {
    alert(
'li tag');
}

ExpandedBlockStart.gifContractedBlock.gifu.onclick 
=   function  (e)  {
    alert(
'ul tag');
    
//阻止冒泡
    stopBubble(e);
}

ExpandedBlockStart.gifContractedBlock.gifd.onclick 
=   function  (e)  {
    alert(
'div tag');
}

< / script>

 

从这个例子中可以看到冒泡以及冒泡被阻止的情况。

 

 

阻止默认行为

 

很多事件具有默认行为,比如点击submit按钮时会提交表单数据及页面转向。

 

阻止冒泡并不能阻止默认行为,因此我们还需要写一个阻止默认行为的函数,并且是通用函数(你可以猜到IE又一次背离了标准)

 

function  stopDefault(e) {
    
if  (e  &&  e.preventDefault)
        e.preventDefault();
    
else
        window.event.returnValue 
=   false ;
    
return   false ;
}

 

 

Dean Edward 的 addEvent 和 removeEvent 函数

 

ContractedBlock.gif ExpandedBlockStart.gif Code
// addEvent/removeEvent written by Dean Edwards, 2005
//
 with input from Tino Zijdel
//
 http://dean.edwards.name/weblog/2005/10/add-event/

ExpandedBlockStart.gifContractedBlock.gif
function addEvent(element, type, handler) {
    
// assign each event handler a unique ID
    if (!handler.$$guid) handler.$$guid = addEvent.guid++;
    
// create a hash table of event types for the element
ExpandedSubBlockStart.gifContractedSubBlock.gif
    if (!element.events) element.events = {};
    
// create a hash table of event handlers for each element/event pair
    var handlers = element.events[type];
ExpandedSubBlockStart.gifContractedSubBlock.gif    
if (!handlers) {
ExpandedSubBlockStart.gifContractedSubBlock.gif        handlers 
= element.events[type] = {};
        
// store the existing event handler (if there is one)
ExpandedSubBlockStart.gifContractedSubBlock.gif
        if (element["on" + type]) {
            handlers[
0= element["on" + type];
        }

    }

    
// store the event handler in the hash table
    handlers[handler.$$guid] = handler;
    
// assign a global event handler to do all the work
    element["on" + type] = handleEvent;
}
;
// a counter used to create unique IDs
addEvent.guid = 1;

ExpandedBlockStart.gifContractedBlock.gif
function removeEvent(element, type, handler) {
    
// delete the event handler from the hash table
ExpandedSubBlockStart.gifContractedSubBlock.gif
    if (element.events && element.events[type]) {
        
delete element.events[type][handler.$$guid];
    }

}
;

ExpandedBlockStart.gifContractedBlock.gif
function handleEvent(event) {
    
var returnValue = true;
    
// grab the event object (IE uses a global event object)
    event = event || fixEvent(window.event);
    
// get a reference to the hash table of event handlers
    var handlers = this.events[event.type];
    
// execute each event handler
ExpandedSubBlockStart.gifContractedSubBlock.gif
    for (var i in handlers) {
        
this.$$handleEvent = handlers[i];
ExpandedSubBlockStart.gifContractedSubBlock.gif        
if (this.$$handleEvent(event) === false{
            returnValue 
= false;
        }

    }

    
return returnValue;
}
;

ExpandedBlockStart.gifContractedBlock.gif
function fixEvent(event) {
    
// add W3C standard event methods
    event.preventDefault = fixEvent.preventDefault;
    event.stopPropagation 
= fixEvent.stopPropagation;
    
return event;
}
;
ExpandedBlockStart.gifContractedBlock.giffixEvent.preventDefault 
= function() {
    
this.returnValue = false;
}
;
ExpandedBlockStart.gifContractedBlock.giffixEvent.stopPropagation 
= function() {
    
this.cancelBubble = true;
}
;

 

Dean Edward的addEvent函数对各个浏览器的支持都很好,因为他采用的是绑定事件处理函数的传统手段;this关键字可以在所有绑定函数中使用,指向的是当前元素;中和了所有防止浏览器默认行为和阻止事件冒泡的各种浏览器特定参数。

 

另外,由于IE缺乏对捕获过程的支持,addEvent仅工作在冒泡阶段。

 

 

转载于:https://www.cnblogs.com/zhengchuyu/archive/2008/07/24/1250455.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值