ExtJs源码分析:class Ext.EventManager

0 views
Skip to first unread message

鸿蒙

unread,
Dec 9, 2008, 3:05:37 AM12/9/08
to 鸿蒙.技术, 软思论坛
  1. /** 
  2.  * author:prk 
  3.  * date:2008-08-01 
  4.  * comment:event analyse. 
  5.  *  
  6.  */  
  7. /* 
  8.  * Ext JS Library 2.0 
  9.  * Copyright(c) 2006-2007, Ext JS, LLC. 
  10.  * lice...@extjs.com 
  11.  *  
  12.  * http://extjs.com/license 
  13.  */  
  14.   
  15. /** 
  16.  * @class Ext.EventManager 
  17.  * Registers event handlers that want to receive a normalized EventObject instead of the standard browser event and provides 
  18.  * several useful events directly. 
  19.  * See {@link Ext.EventObject} for more details on normalized event objects. 
  20.  * @singleton 
  21.  */  
  22. Ext.EventManager = function(){  
  23.     var docReadyEvent, docReadyProcId, docReadyState = false;  
  24.     var resizeEvent, resizeTask, textEvent, textSize;  
  25.     var E = Ext.lib.Event;  
  26.     var D = Ext.lib.Dom;  
  27.   
  28.   //docReady的监听函数  
  29.     var fireDocReady = function(){  
  30.         if(!docReadyState){  
  31.             //设定加载完成的标识  
  32.             docReadyState = true;  
  33.             Ext.isReady = true;  
  34.              
  35.             //对于Safari,成功刚应该clearInterval  
  36.             if(docReadyProcId){  
  37.                 clearInterval(docReadyProcId);  
  38.             }  
  39.             //现在到了remove DOMContentLoaded的事件监听了。  
  40.             if(Ext.isGecko || Ext.isOpera) {  
  41.                 document.removeEventListener("DOMContentLoaded", fireDocReady, false);  
  42.             }  
  43.             //Ie,则remove 生成的元素。  
  44.             if(Ext.isIE){  
  45.                 var defer = document.getElementById("ie-deferred-loader");  
  46.                 if(defer){  
  47.                     defer.onreadystatechange = null;  
  48.                     defer.parentNode.removeChild(defer);  
  49.                 }  
  50.             }  
  51.             //执行docReadyEvent中监听之后除去Listeners  
  52.             if(docReadyEvent){  
  53.                 docReadyEvent.fire();  
  54.                 docReadyEvent.clearListeners();  
  55.             }  
  56.         }  
  57.     };  
  58.       
  59.      //初始化docReady  
  60.     var initDocReady = function(){  
  61.         docReadyEvent = new Ext.util.Event();  
  62.         //对于Opera、Gecko.为document的DOMContentLoaded事件注册fireDocReady监听。  
  63.         if(Ext.isGecko || Ext.isOpera) {  
  64.             document.addEventListener("DOMContentLoaded", fireDocReady, false);  
  65.         }//对于IE,通过强行在document加入一个元素,判断这个元素是否加载完来判断文档是否加载完  
  66.         //如果加载完了该元素的onreadystatechange的回调函数中的readyState == "complete"  
  67.         else if(Ext.isIE){  
  68.             document.write("<s"+'cript id="ie-deferred-loader" defer="defer" src="/'+'/:"></s'+"cript>");  
  69.             var defer = document.getElementById("ie-deferred-loader");  
  70.             defer.onreadystatechange = function(){  
  71.                 if(this.readyState == "complete"){  
  72.                     fireDocReady();  
  73.                 }  
  74.             };  
  75.         }  
  76.         //对于Safari,每隔10ms监听它的document.readyState是否==="complete"  
  77.         else if(Ext.isSafari){  
  78.             docReadyProcId = setInterval(function(){  
  79.                 var rs = document.readyState;  
  80.                 if(rs == "complete") {  
  81.                     fireDocReady();  
  82.                  }  
  83.             }, 10);  
  84.         }  
  85.         //觉得这里没有必要采用Ext.lib.event.  
  86.         // no matter what, make sure it fires on load  
  87.         E.on(window, "load", fireDocReady);  
  88.     };  
  89.      
  90.     //隔多长时间执行一次h函数。  
  91.     var createBuffered = function(h, o){  
  92.         var task = new Ext.util.DelayedTask(h);  
  93.         return function(e){  
  94.             // create new event object impl so new events don't wipe out properties  
  95.             e = new Ext.EventObjectImpl(e);  
  96.             task.delay(o.buffer, h, null, [e]);  
  97.         };  
  98.     };  
  99.   
  100.     //一个监听执行一次就被remove  
  101.     var createSingle = function(h, el, ename, fn){  
  102.         return function(e){  
  103.             Ext.EventManager.removeListener(el, ename, fn);  
  104.             h(e);  
  105.         };  
  106.     };  
  107.   
  108.     //多长时间之后执行h函数  
  109.     var createDelayed = function(h, o){  
  110.         return function(e){  
  111.             // create new event object impl so new events don't wipe out properties  
  112.             e = new Ext.EventObjectImpl(e);  
  113.             setTimeout(function(){  
  114.                 h(e);  
  115.             }, o.delay || 10);  
  116.         };  
  117.     };  
  118.       
  119.     //为element的ename事件添加fn的监听函数。  
  120.     var listen = function(element, ename, opt, fn, scope){  
  121.         var o = (!opt || typeof opt == "boolean") ? {} : opt;  
  122.         fn = fn || o.fn; scope = scope || o.scope;  
  123.         var el = Ext.getDom(element);  
  124.         if(!el){  
  125.             throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';  
  126.         }  
  127.         //对传进来的fn进行包装  
  128.         var h = function(e){  
  129.             e = Ext.EventObject.setEvent(e);  
  130.             var t;  
  131.             //找到事件的元素或附近的元素,o.delegate是select  
  132.             if(o.delegate){  
  133.                 t = e.getTarget(o.delegate, el);  
  134.                 if(!t){  
  135.                     return;  
  136.                 }  
  137.             }else{  
  138.                 t = e.target;  
  139.             }  
  140.             //对元素事件的三种操作,一:stop,二、preventDefault,三、stopPropagation  
  141.             if(o.stopEvent === true){  
  142.                 e.stopEvent();  
  143.             }  
  144.             if(o.preventDefault === true){  
  145.                e.preventDefault();  
  146.             }  
  147.             if(o.stopPropagation === true){  
  148.                 e.stopPropagation();  
  149.             }  
  150.              //是否采用原始的浏览事件e,而不是进行了包装的事件。  
  151.             if(o.normalized === false){  
  152.                 e = e.browserEvent;  
  153.             }  
  154.              //fn(event,this,options)  
  155.             fn.call(scope || el, e, t, o);  
  156.         };  
  157.           
  158.         //推迟执行  
  159.         if(o.delay){  
  160.             h = createDelayed(h, o);  
  161.         }  
  162.         //监听只执行一次  
  163.         if(o.single){  
  164.             h = createSingle(h, el, ename, fn);  
  165.         }  
  166.         //隔多少时间就执行一次  
  167.         if(o.buffer){  
  168.             h = createBuffered(h, o);  
  169.         }  
  170.         fn._handlers = fn._handlers || [];  
  171.         fn._handlers.push([Ext.id(el), ename, h]);  
  172.           
  173.         //为el的ename事件注册h函数。  
  174.         E.on(el, ename, h);  
  175.           
  176.         if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery  
  177.             el.addEventListener("DOMMouseScroll", h, false);  
  178.             E.on(window, 'unload', function(){  
  179.                 el.removeEventListener("DOMMouseScroll", h, false);  
  180.             });  
  181.         }  
  182.         //对document的mousedown,在stopEvent等中要先fire,之后才stop.  
  183.         if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document  
  184.             Ext.EventManager.stoppedMouseDownEvent.addListener(h);  
  185.         }  
  186.         return h;  
  187.     };  
  188.   
  189.     var stopListening = function(el, ename, fn){  
  190.         var id = Ext.id(el), hds = fn._handlers, hd = fn;  
  191.         if(hds){  
  192.             for(var i = 0, len = hds.length; i < len; i++){  
  193.                 var h = hds[i];  
  194.                 if(h[0] == id && h[1] == ename){  
  195.                     hd = h[2];  
  196.                     hds.splice(i, 1);  
  197.                     break;  
  198.                 }  
  199.             }  
  200.         }  
  201.         E.un(el, ename, hd);  
  202.         el = Ext.getDom(el);  
  203.         if(ename == "mousewheel" && el.addEventListener){  
  204.             el.removeEventListener("DOMMouseScroll", hd, false);  
  205.         }  
  206.         if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document  
  207.             Ext.EventManager.stoppedMouseDownEvent.removeListener(hd);  
  208.         }  
  209.     };  
  210.   
  211.     var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;  
  212.     var pub = {  
  213.   
  214.     /** 
  215.      * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will 
  216.      * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version. 
  217.      * @param {String/HTMLElement} el The html element or id to assign the event handler to 
  218.      * @param {String} eventName The type of event to listen for 
  219.      * @param {Function} handler The handler function the event invokes 
  220.      * @param {Object} scope (optional) The scope in which to execute the handler 
  221.      * function (the handler function's "this" context) 
  222.      * @param {Object} options (optional) An object containing handler configuration properties. 
  223.      * This may contain any of the following properties:<ul> 
  224.      * <li>scope {Object} : The scope in which to execute the handler function. The handler function's "this" context.</li> 
  225.      * <li>delegate {String} : A simple selector to filter the target or look for a descendant of the target</li> 
  226.      * <li>stopEvent {Boolean} : True to stop the event. That is stop propagation, and prevent the default action.</li> 
  227.      * <li>preventDefault {Boolean} : True to prevent the default action</li> 
  228.      * <li>stopPropagation {Boolean} : True to prevent event propagation</li> 
  229.      * <li>normalized {Boolean} : False to pass a browser event to the handler function instead of an Ext.EventObject</li> 
  230.      * <li>delay {Number} : The number of milliseconds to delay the invocation of the handler after te event fires.</li> 
  231.      * <li>single {Boolean} : True to add a handler to handle just the next firing of the event, and then remove itself.</li> 
  232.      * <li>buffer {Number} : Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed 
  233.      * by the specified number of milliseconds. If the event fires again within that time, the original 
  234.      * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</li> 
  235.      * </ul><br> 
  236.      * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p> 
  237.      */  
  238.         //支持和observable中addListener一样的传参的形式  
  239.         //这个函数和observable中addListener的结构差不多。不同的把具体的处理放到listen中。  
  240.         addListener : function(element, eventName, fn, scope, options){  
  241.             if(typeof eventName == "object"){  
  242.                 var o = eventName;  
  243.                 for(var e in o){  
  244.                     if(propRe.test(e)){  
  245.                         continue;  
  246.                     }  
  247.                     if(typeof o[e] == "function"){  
  248.                         // shared options  
  249.                         listen(element, e, o, o[e], o.scope);  
  250.                     }else{  
  251.                         // individual options  
  252.                         listen(element, e, o[e]);  
  253.                     }  
  254.                 }  
  255.                 return;  
  256.             }  
  257.             return listen(element, eventName, options, fn, scope);  
  258.         },  
  259.   
  260.         /** 
  261.          * Removes an event handler from an element.  The shorthand version {@link #un} is equivalent.  Typically 
  262.          * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version. 
  263.          * @param {String/HTMLElement} el The id or html element from which to remove the event 
  264.          * @param {String} eventName The type of event 
  265.          * @param {Function} fn The handler function to remove 
  266.          * @return {Boolean} True if a listener was actually removed, else false 
  267.          */  
  268.         removeListener : function(element, eventName, fn){  
  269.             return stopListening(element, eventName, fn);  
  270.         },  
  271.   
  272.         /** 
  273.          * Fires when the document is ready (before onload and before images are loaded). Can be 
  274.          * accessed shorthanded as Ext.onReady(). 
  275.          * @param {Function} fn The method the event invokes 
  276.          * @param {Object} scope (optional) An object that becomes the scope of the handler 
  277.          * @param {boolean} options (optional) An object containing standard {@link #addListener} options 
  278.          */  
  279.         onDocumentReady : function(fn, scope, options){  
  280.            //document已经load,为docReadyEvent 进行addListener、fire(),clearListeners();  
  281.             if(docReadyState){ // if it already fired  
  282.                 docReadyEvent.addListener(fn, scope, options);  
  283.                 docReadyEvent.fire();  
  284.                 docReadyEvent.clearListeners();  
  285.                 return;  
  286.             }  
  287.             //初始化Document Ready.  
  288.             if(!docReadyEvent){  
  289.                 initDocReady();  
  290.             }  
  291.             //初始化之后再addListener  
  292.             docReadyEvent.addListener(fn, scope, options);  
  293.         },  
  294.   
  295.         /** 
  296.          * Fires when the window is resized and provides resize event buffering (50 milliseconds), passes new viewport width and height to handlers. 
  297.          * @param {Function} fn        The method the event invokes 
  298.          * @param {Object}   scope    An object that becomes the scope of the handler 
  299.          * @param {boolean}  options 
  300.          */  
  301.         onWindowResize : function(fn, scope, options){  
  302.             if(!resizeEvent){  
  303.                 resizeEvent = new Ext.util.Event();  
  304.                 resizeTask = new Ext.util.DelayedTask(function(){  
  305.                     resizeEvent.fire(D.getViewWidth(), D.getViewHeight());  
  306.                 });  
  307.                 E.on(window, "resize"this.fireWindowResize, this);  
  308.             }  
  309.             resizeEvent.addListener(fn, scope, options);  
  310.         },  
  311.   
  312.         // exposed only to allow manual firing  
  313.         fireWindowResize : function(){  
  314.             if(resizeEvent){  
  315.                 if((Ext.isIE||Ext.isAir) && resizeTask){  
  316.                     resizeTask.delay(50);  
  317.                 }else{  
  318.                     resizeEvent.fire(D.getViewWidth(), D.getViewHeight());  
  319.                 }  
  320.             }  
  321.         },  
  322.   
  323.         /** 
  324.          * Fires when the user changes the active text size. Handler gets called with 2 params, the old size and the new size. 
  325.          * @param {Function} fn        The method the event invokes 
  326.          * @param {Object}   scope    An object that becomes the scope of the handler 
  327.          * @param {boolean}  options 
  328.          */  
  329.         onTextResize : function(fn, scope, options){  
  330.             if(!textEvent){  
  331.                 textEvent = new Ext.util.Event();  
  332.                 var textEl = new Ext.Element(document.createElement('div'));  
  333.                 textEl.dom.className = 'x-text-resize';  
  334.                 textEl.dom.innerHTML = 'X';  
  335.                 textEl.appendTo(document.body);  
  336.                 textSize = textEl.dom.offsetHeight;  
  337.                 setInterval(function(){  
  338.                     if(textEl.dom.offsetHeight != textSize){  
  339.                         textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);  
  340.                     }  
  341.                 }, this.textResizeInterval);  
  342.             }  
  343.             textEvent.addListener(fn, scope, options);  
  344.         },  
  345.   
  346.         /** 
  347.          * Removes the passed window resize listener. 
  348.          * @param {Function} fn        The method the event invokes 
  349.          * @param {Object}   scope    The scope of handler 
  350.          */  
  351.         removeResizeListener : function(fn, scope){  
  352.             if(resizeEvent){  
  353.                 resizeEvent.removeListener(fn, scope);  
  354.             }  
  355.         },  
  356.   
  357.         // private  
  358.         fireResize : function(){  
  359.             if(resizeEvent){  
  360.                 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());  
  361.             }  
  362.         },  
  363.         /** 
  364.          * Url used for onDocumentReady with using SSL (defaults to Ext.SSL_SECURE_URL) 
  365.          */  
  366.         ieDeferSrc : false,  
  367.         /** 
  368.          * The frequency, in milliseconds, to check for text resize events (defaults to 50) 
  369.          */  
  370.         textResizeInterval : 50  
  371.     };  
  372.      /** 
  373.      * Appends an event handler to an element.  Shorthand for {@link #addListener}. 
  374.      * @param {String/HTMLElement} el The html element or id to assign the event handler to 
  375.      * @param {String} eventName The type of event to listen for 
  376.      * @param {Function} handler The handler function the event invokes 
  377.      * @param {Object} scope (optional) The scope in which to execute the handler 
  378.      * function (the handler function's "this" context) 
  379.      * @param {Object} options (optional) An object containing standard {@link #addListener} options 
  380.      * @member Ext.EventManager 
  381.      * @method on 
  382.      */  
  383.     pub.on = pub.addListener;  
  384.     /** 
  385.      * Removes an event handler from an element.  Shorthand for {@link #removeListener}. 
  386.      * @param {String/HTMLElement} el The id or html element from which to remove the event 
  387.      * @param {String} eventName The type of event 
  388.      * @param {Function} fn The handler function to remove 
  389.      * @return {Boolean} True if a listener was actually removed, else false 
  390.      * @member Ext.EventManager 
  391.      * @method un 
  392.      */  
  393.     pub.un = pub.removeListener;  
  394.   
  395.     pub.stoppedMouseDownEvent = new Ext.util.Event();  
  396.     return pub;  
  397. }();  
  398. /** 
  399.   * Fires when the document is ready (before onload and before images are loaded).  Shorthand of {@link Ext.EventManager#onDocumentReady}. 
  400.   * @param {Function} fn        The method the event invokes 
  401.   * @param {Object}   scope    An  object that becomes the scope of the handler 
  402.   * @param {boolean}  override If true, the obj passed in becomes 
  403.   *                             the execution scope of the listener 
  404.   * @member Ext 
  405.   * @method onReady 
  406.  */  
  407. Ext.onReady = Ext.EventManager.onDocumentReady;  
  408.   
  409. Ext.onReady(function(){  
  410.     var bd = Ext.getBody();  
  411.     if(!bd){ return; }  
  412.   
  413.     var cls = [  
  414.             Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : 'ext-ie7')  
  415.             : Ext.isGecko ? "ext-gecko"  
  416.             : Ext.isOpera ? "ext-opera"  
  417.             : Ext.isSafari ? "ext-safari" : ""];  
  418.   
  419.     if(Ext.isMac){  
  420.         cls.push("ext-mac");  
  421.     }  
  422.     if(Ext.isLinux){  
  423.         cls.push("ext-linux");  
  424.     }  
  425.     if(Ext.isBorderBox){  
  426.         cls.push('ext-border-box');  
  427.     }  
  428.     if(Ext.isStrict){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"  
  429.         var p = bd.dom.parentNode;  
  430.         if(p){  
  431.             p.className += ' ext-strict';  
  432.         }  
  433.     }  
  434.     bd.addClass(cls.join(' '));  
  435. });  
  436.   
  437. /** 
  438.  * @class Ext.EventObject 
  439.  * EventObject exposes the Yahoo! UI Event functionality directly on the object 
  440.  * passed to your event handler. It exists mostly for convenience. It also fixes the annoying null checks automatically to cleanup your code 
  441.  * Example: 
  442.  * <pre><code> 
  443.  function handleClick(e){ // e is not a standard event object, it is a Ext.EventObject 
  444.     e.preventDefault(); 
  445.     var target = e.getTarget(); 
  446.     ... 
  447.  } 
  448.  var myDiv = Ext.get("myDiv"); 
  449.  myDiv.on("click", handleClick); 
  450.  //or 
  451.  Ext.EventManager.on("myDiv", 'click', handleClick); 
  452.  Ext.EventManager.addListener("myDiv", 'click', handleClick); 
  453.  </code></pre> 
  454.  * @singleton 
  455.  */  
  456. Ext.EventObject = function(){  
  457.   
  458.     var E = Ext.lib.Event;  
  459.   
  460.     // safari keypress events for special keys return bad keycodes  
  461.     var safariKeys = {  
  462.         63234 : 37// left  
  463.         63235 : 39// right  
  464.         63232 : 38// up  
  465.         63233 : 40// down  
  466.         63276 : 33// page up  
  467.         63277 : 34// page down  
  468.         63272 : 46// delete  
  469.         63273 : 36// home  
  470.         63275 : 35  // end  
  471.     };  
  472.   
  473.     // normalize button clicks  
  474.     //表示鼠标的左,中,右键,每种浏览器不一同,统一为0,1,2.  
  475.     var btnMap = Ext.isIE ? {1:0,4:1,2:2} :  
  476.                 (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2});  
  477.   
  478.     Ext.EventObjectImpl = function(e){  
  479.         if(e){  
  480.             this.setEvent(e.browserEvent || e);  
  481.         }  
  482.     };  
  483.     Ext.EventObjectImpl.prototype = {  
  484.         /** The normal browser event */  
  485.         browserEvent : null,  
  486.         /** The button pressed in a mouse event */  
  487.         button : -1,  
  488.         /** True if the shift key was down during the event */  
  489.         shiftKey : false,  
  490.         /** True if the control key was down during the event */  
  491.         ctrlKey : false,  
  492.         /** True if the alt key was down during the event */  
  493.         altKey : false,  
  494.            
  495.         //一些常用的按键。  
  496.         /** Key constant @type Number */  
  497.         BACKSPACE : 8,  
  498.         /** Key constant @type Number */  
  499.         TAB : 9,  
  500.         /** Key constant @type Number */  
  501.         RETURN : 13,  
  502.         /** Key constant @type Number */  
  503.         ENTER : 13,  
  504.         /** Key constant @type Number */  
  505.         SHIFT : 16,  
  506.         /** Key constant @type Number */  
  507.         CONTROL : 17,  
  508.         /** Key constant @type Number */  
  509.         ESC : 27,  
  510.         /** Key constant @type Number */  
  511.         SPACE : 32,  
  512.         /** Key constant @type Number */  
  513.         PAGEUP : 33,  
  514.         /** Key constant @type Number */  
  515.         PAGEDOWN : 34,  
  516.         /** Key constant @type Number */  
  517.         END : 35,  
  518.         /** Key constant @type Number */  
  519.         HOME : 36,  
  520.         /** Key constant @type Number */  
  521.         LEFT : 37,  
  522.         /** Key constant @type Number */  
  523.         UP : 38,  
  524.         /** Key constant @type Number */  
  525.         RIGHT : 39,  
  526.         /** Key constant @type Number */  
  527.         DOWN : 40,  
  528.         /** Key constant @type Number */  
  529.         DELETE : 46,  
  530.         /** Key constant @type Number */  
  531.         F5 : 116,  
  532.   
  533.            /** @private */  
  534.         //包装事件。  
  535.         setEvent : function(e){  
  536.             if(e == this || (e && e.browserEvent)){ // already wrapped  
  537.                 return e;  
  538.             }  
  539.             //设定 this.browserEvent=传入的浏览器的event,做为是否包装的标识。  
  540.             this.browserEvent = e;  
  541.             if(e){  
  542.                 // normalize buttons,比prototype实现简单多了。表示鼠标按键。  
  543.                 this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1);  
  544.                 if(e.type == 'click' && this.button == -1){  
  545.                     this.button = 0;  
  546.                 }  
  547.                 //事件名  
  548.                 this.type = e.type;  
  549.                   
  550.                 //三个功能组合键  
  551.                 this.shiftKey = e.shiftKey;  
  552.                 // mac metaKey behaves like ctrlKey  
  553.                 this.ctrlKey = e.ctrlKey || e.metaKey;  
  554.                 this.altKey = e.altKey;  
  555.                  
  556.                 //键盘事件的keywode,and charcode  
  557.                 // in getKey these will be normalized for the mac  
  558.                 this.keyCode = e.keyCode;  
  559.                 this.charCode = e.charCode;  
  560.                   
  561.                 //我倒是觉得这里的不好,不应该采用 Ext.lib.Event,组合在一起很方便啊  
  562.                 //可能是出于版本兼容等问题的考虑吧。  
  563.                 // cache the target for the delayed and or buffered events  
  564.                 this.target = E.getTarget(e);  
  565.                 // same for XY  
  566.                 this.xy = E.getXY(e);  
  567.             }else{  
  568.                 this.button = -1;  
  569.                 this.shiftKey = false;  
  570.                 this.ctrlKey = false;  
  571.                 this.altKey = false;  
  572.                 this.keyCode = 0;  
  573.                 this.charCode =0;  
  574.                 this.target = null;  
  575.                 this.xy = [00];  
  576.             }  
  577.             return this;  
  578.         },  
  579.   
  580.         /** 
  581.          * Stop the event (preventDefault and stopPropagation) 
  582.          */  
  583.         //觉得stopEvent,preventDefault,stopPropagation完全可以独立实现。  
  584.         stopEvent : function(){  
  585.             if(this.browserEvent){  
  586.                 if(this.browserEvent.type == 'mousedown'){  
  587.                     Ext.EventManager.stoppedMouseDownEvent.fire(this);  
  588.                 }  
  589.                 E.stopEvent(this.browserEvent);  
  590.             }  
  591.         },  
  592.   
  593.         /** 
  594.          * Prevents the browsers default handling of the event. 
  595.          */  
  596.         // this.browserEven.returnValue = false;          
  597.         preventDefault : function(){  
  598.             if(this.browserEvent){  
  599.                 E.preventDefault(this.browserEvent);  
  600.             }  
  601.         },  
  602.   
  603.         /** @private */  
  604.         //判断键是不是字符按键,除去了一些功能键  
  605.         isNavKeyPress : function(){  
  606.             var k = this.keyCode;  
  607.             k = Ext.isSafari ? (safariKeys[k] || k) : k;  
  608.             return (k >= 33 && k <= 40) || k == this.RETURN || k == this.TAB || k == this.ESC;  
  609.         },  
  610.           
  611.         //判断是不是特殊键。  
  612.         isSpecialKey : function(){  
  613.             var k = this.keyCode;  
  614.             return (this.type == 'keypress' && this.ctrlKey) || k == 9 || k == 13  || k == 40 || k == 27 ||  
  615.             (k == 16) || (k == 17) ||  
  616.             (k >= 18 && k <= 20) ||  
  617.             (k >= 33 && k <= 35) ||  
  618.             (k >= 36 && k <= 39) ||  
  619.             (k >= 44 && k <= 45);  
  620.         },  
  621.         /** 
  622.          * Cancels bubbling of the event. 
  623.          */  
  624.         //this.browserEvent.cancelBubble=false  
  625.         stopPropagation : function(){  
  626.             if(this.browserEvent){  
  627.                 if(this.browserEvent.type == 'mousedown'){  
  628.                     Ext.EventManager.stoppedMouseDownEvent.fire(this);  
  629.                 }  
  630.                 E.stopPropagation(this.browserEvent);  
  631.             }  
  632.         },  
  633.           
  634.        //取得键值和其代码  
  635.         /** 
  636.          * Gets the key code for the event. 
  637.          * @return {Number} 
  638.          */  
  639.         getCharCode : function(){  
  640.             return this.charCode || this.keyCode;  
  641.         },  
  642.   
  643.         /** 
  644.          * Returns a normalized keyCode for the event. 
  645.          * @return {Number} The key code 
  646.          */  
  647.         getKey : function(){  
  648.             var k = this.keyCode || this.charCode;  
  649.             return Ext.isSafari ? (safariKeys[k] || k) : k;  
  650.         },  
  651.           
  652.         //取得事件页面的位置  
  653.         /** 
  654.          * Gets the x coordinate of the event. 
  655.          * @return {Number} 
  656.          */  
  657.         getPageX : function(){  
  658.             return this.xy[0];  
  659.         },  
  660.   
  661.         /** 
  662.          * Gets the y coordinate of the event. 
  663.          * @return {Number} 
  664.          */  
  665.         getPageY : function(){  
  666.             return this.xy[1];  
  667.         },  
  668.   
  669.         /** 
  670.          * Gets the time of the event. 
  671.          * @return {Number} 
  672.          */  
  673.         getTime : function(){  
  674.             if(this.browserEvent){  
  675.                 return E.getTime(this.browserEvent);  
  676.             }  
  677.             return null;  
  678.         },  
  679.   
  680.         /** 
  681.          * Gets the page coordinates of the event. 
  682.          * @return {Array} The xy values like [x, y] 
  683.          */  
  684.         getXY : function(){  
  685.             return this.xy;  
  686.         },  
  687.   
  688.         /** 
  689.          * Gets the target for the event. 
  690.          * @param {String} selector (optional) A simple selector to filter the target or look for an ancestor of the target 
  691.          * @param {Number/Mixed} maxDepth (optional) The max depth to 
  692.                 search as a number or element (defaults to 10 || document.body) 
  693.          * @param {Boolean} returnEl (optional) True to return a Ext.Element object instead of DOM node 
  694.          * @return {HTMLelement} 
  695.          */  
  696.         //和prototype中findElement差不多,找到事件源元素附近的元素。  
  697.         getTarget : function(selector, maxDepth, returnEl){  
  698.             var t = Ext.get(this.target);  
  699.             return selector ? t.findParent(selector, maxDepth, returnEl) : (returnEl ? t : this.target);  
  700.         },  
  701.           
  702.         /** 
  703.          * Gets the related target. 
  704.          * @return {HTMLElement} 
  705.          */  
  706.         getRelatedTarget : function(){  
  707.             if(this.browserEvent){  
  708.                 return E.getRelatedTarget(this.browserEvent);  
  709.             }  
  710.             return null;  
  711.         },  
  712.   
  713.         /** 
  714.          * Normalizes mouse wheel delta across browsers 
  715.          * @return {Number} The delta 
  716.          */  
  717.         getWheelDelta : function(){  
  718.             var e = this.browserEvent;  
  719.             var delta = 0;  
  720.             if(e.wheelDelta){ /* IE/Opera. */  
  721.                 delta = e.wheelDelta/120;  
  722.             }else if(e.detail){ /* Mozilla case. */  
  723.                 delta = -e.detail/3;  
  724.             }  
  725.             return delta;  
  726.         },  
  727.   
  728.         /** 
  729.          * Returns true if the control, meta, shift or alt key was pressed during this event. 
  730.          * @return {Boolean} 
  731.          */  
  732.         hasModifier : function(){  
  733.             return ((this.ctrlKey || this.altKey) || this.shiftKey) ? true : false;  
  734.         },  
  735.   
  736.         /** 
  737.          * Returns true if the target of this event equals el or is a child of el 
  738.          * @param {Mixed} el 
  739.          * @param {Boolean} related (optional) true to test if the related target is within el instead of the target 
  740.          * @return {Boolean} 
  741.          */  
  742.         within : function(el, related){  
  743.             var t = this[related ? "getRelatedTarget" : "getTarget"]();  
  744.             return t && Ext.fly(el).contains(t);  
  745.         },  
  746.   
  747.         getPoint : function(){  
  748.             return new Ext.lib.Point(this.xy[0], this.xy[1]);  
  749.         }  
  750.     };  
  751.   
  752.     return new Ext.EventObjectImpl();  
  753. }(); 
Reply all
Reply to author
Forward
0 new messages