[转帖]Mootools源码分析-17 -- Element-4

原帖地址:http://space.flash8.net/space/?18713/viewspace-403269.html

原作者:我佛山人

 

// Element事件的setter,addEvents的快捷方式

Element.Properties.events 
=  {set:  function (events)    {

    
this .addEvents(events);

}};

// Element、Window 和 Document的事件扩展

Native.implement([Element, Window, Document], {

    
// 添加事件监听,有别于addListener,可以使用自定义事件
    addEvent:  function (type, fn)    {
        
// 取临时对象,注意提供的默认值
         var  events  =   this .retrieve( ' events ' , {});
        
// 查找指定类型的事件列表
        events[type]  =  events[type]  ||  { ' keys ' : [],  ' values ' : []};
        
// 如果已经添加了该监听
         if  (events[type].keys.contains(fn))     return   this ;
        
// 添加到事件订阅列表
        events[type].keys.push(fn);
        
var  realType  =  type, custom  =  Element.Events.get(type), condition  =  fn, self  =   this ;
        
// 如果是自定义事件
         if  (custom)    {
        
// 添加自定义事件时的处理
             if  (custom.onAdd)    custom.onAdd.call( this , fn);
        
// 自定义事件的条件
             if  (custom.condition)    {
                condition 
=   function (event)    {
                    
if  (custom.condition.call( this , event))     return  fn.call( this , event);
                    
return   false ;
                };
            }
            realType 
=  custom.base  ||  realType;
        }
        
var  defn  =   function ()    {
            
return  fn.call(self);
        };
        
// 内置事件类型处理    
         var  nativeEvent  =  Element.NativeEvents[realType]  ||   0 ;
        
// 如果是内置的事件
         if  (nativeEvent)    {
            
// 如果是交互事件
             if  (nativeEvent  ==   2 )    {
                
// 闭包
                defn  =   function (event)    {
                
// 这样最后传给监听函数的参数是经包装过Event对象
                    event  =   new  Event(event, self.getWindow());
                    
// 这个条件用于扩展内置事件
                     if  (condition.call(self, event)  ===   false )    event.stop();
                };
            }
            
// 最终还是调用addListener
             this .addListener(realType, defn);
        }
        
// 添加到列表
        events[type].values.push(defn);
        
return   this ;
    },


    
// 移除事件监听

    removeEvent: 
function (type, fn)    {

        
// 取临时对象,不提供默认值
         var  events  =   this .retrieve( ' events ' );
        
// 如果临时对象不存在,说明监听不存在,直接返回
         if  ( ! events  ||   ! events[type])     return   this ;
        
// 检查是否已添加本监听
         var  pos  =  events[type].keys.indexOf(fn);
        
// 没有则返回
         if  (pos  ==   - 1 )     return   this ;
        
// 从队列中移除
         var  key  =  events[type].keys.splice(pos,  1 )[ 0 ];
        
var  value  =  events[type].values.splice(pos,  1 )[ 0 ];
        
// 自定义事件处理
         var  custom  =  Element.Events.get(type);
        
// 如果是自定义事件
         if  (custom)    {
            
// 自定义事件的移除处理
             if  (custom.onRemove)    custom.onRemove.call( this , fn);
            type 
=  custom.base  ||  type;
        }
        
// 如果是内置事件还需要调用removeListener来处理
         return  (Element.NativeEvents[type])  ?   this .removeListener(type, value) :  this ;
    },
    
    
// 批量添加事件监听
    addEvents:  function (events)    {
        
for  ( var  event  in  events)     this .addEvent(event, events[event]);
        
return   this ;
    },

// 批量移除事件监听
    removeEvents:  function (type)    {
        
// 取临时对象,不提供默认值
         var  events  =   this .retrieve( ' events ' );
        
// 没有事件监听直接返回
         if  ( ! events)     return   this ;
        
// 如果不提供type参数,移除所有类型的事件
         if  ( ! type)    {
            
for  ( var  evType  in  events)  this .removeEvents(evType);
            events 
=   null ;
        }    
else   if  (events[type])    {
            
// 移除指定类型的事件
             while  (events[type].keys[ 0 ])     this .removeEvent(type, events[type].keys[ 0 ]);
            events[type] 
=   null ;
        }
        
return   this ;
    },

    
// 事件通知
    fireEvent:  function (type, args, delay)    {
        
// 取临时对象,不提供默认值
         var  events  =   this .retrieve( ' events ' );
        
// 没有事件监听
         if  ( ! events  ||   ! events[type])     return   this ;
        events[type].keys.each(
function (fn)    {
            
// 注意事件监听的函数中this默认指向当前Element
            fn.create({ ' bind ' this ' delay ' : delay,  ' arguments ' : args})();
        }, 
this );
        
return   this ;
    },

    
// 事件复制
    cloneEvents:  function (from, type)    {
        
// 事件源
        from  =  $(from);
        
var  fevents  =  from.retrieve( ' events ' );
        
if  ( ! fevents)     return   this ;
        
// 不提供type参数则复制所有事件
         if  ( ! type)    {
            
for  ( var  evType  in  fevents)     this .cloneEvents(from, evType);
        }    
else   if  (fevents[type])    {
        
// 复制指定类型的事件
            fevents[type].keys.each( function (fn)    {
                
this .addEvent(type, fn);
            }, 
this );
        }
        
return   this ;
    }
});


// 内置事件,分两种类型

Element.NativeEvents 
=  {
    click: 
2 , dblclick:  2 , mouseup:  2 , mousedown:  2 , contextmenu:  2 // mouse buttons
    mousewheel:  2 , DOMMouseScroll:  2 // mouse wheel
    mouseover:  2 , mouseout:  2 , mousemove:  2 , selectstart:  2 , selectend:  2 // mouse movement
    keydown:  2 , keypress:  2 , keyup:  2 // keyboard
    focus:  2 , blur:  2 , change:  2 , reset:  2 , select:  2 , submit:  2 // form elements
    load:  1 , unload:  1 , beforeunload:  1 , resize:  1 , move:  1 , DOMContentLoaded:  1 , readystatechange:  1 // window
    error:  1 , abort:  1 , scroll:  1   // misc
};

// 就地执行的匿名函数
( function ()    {
    
var  $check  =   function (event)    {
        
var  related  =  event.relatedTarget;
        
if  (related  ==  undefined)     return   true ;
        
if  (related  ===   false )     return   false ;
        
return  ($type( this !=   ' document '   &&  related  !=   this   &&  related.prefix  !=   ' xul '   &&   ! this .hasChild(related));
    };

    
// 基于原事件扩展出的自定义事件
    Element.Events  =   new  Hash({
        
// 鼠标进入事件
        mouseenter: {
            base: 
' mouseover ' ,
            condition: $check
        },
        
// 鼠标离开事件
        mouseleave: {
            base: 
' mouseout ' ,
            condition: $check
        },
// 鼠标滚轮事件
        mousewheel: {
            base: (Browser.Engine.gecko) 
?   ' DOMMouseScroll '  :  ' mousewheel '
        }
    });
})();

 

转载于:https://www.cnblogs.com/maapaa/articles/mootools-s-17.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值