ext-base-event.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:11k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!
  2.  * Ext JS Library 3.1.0
  3.  * Copyright(c) 2006-2009 Ext JS, LLC
  4.  * licensing@extjs.com
  5.  * http://www.extjs.com/license
  6.  */
  7. Ext.lib.Event = function() {
  8.     var loadComplete = false,
  9.         unloadListeners = {},
  10.         retryCount = 0,
  11.         onAvailStack = [],
  12.         _interval,
  13.         locked = false,
  14.         win = window,
  15.         doc = document,
  16.         // constants
  17.         POLL_RETRYS = 200,
  18.         POLL_INTERVAL = 20,
  19.         EL = 0,
  20.         TYPE = 0,
  21.         FN = 1,
  22.         WFN = 2,
  23.         OBJ = 2,
  24.         ADJ_SCOPE = 3,
  25.         SCROLLLEFT = 'scrollLeft',
  26.         SCROLLTOP = 'scrollTop',
  27.         UNLOAD = 'unload',
  28.         MOUSEOVER = 'mouseover',
  29.         MOUSEOUT = 'mouseout',
  30.         // private
  31.         doAdd = function() {
  32.             var ret;
  33.             if (win.addEventListener) {
  34.                 ret = function(el, eventName, fn, capture) {
  35.                     if (eventName == 'mouseenter') {
  36.                         fn = fn.createInterceptor(checkRelatedTarget);
  37.                         el.addEventListener(MOUSEOVER, fn, (capture));
  38.                     } else if (eventName == 'mouseleave') {
  39.                         fn = fn.createInterceptor(checkRelatedTarget);
  40.                         el.addEventListener(MOUSEOUT, fn, (capture));
  41.                     } else {
  42.                         el.addEventListener(eventName, fn, (capture));
  43.                     }
  44.                     return fn;
  45.                 };
  46.             } else if (win.attachEvent) {
  47.                 ret = function(el, eventName, fn, capture) {
  48.                     el.attachEvent("on" + eventName, fn);
  49.                     return fn;
  50.                 };
  51.             } else {
  52.                 ret = function(){};
  53.             }
  54.             return ret;
  55.         }(),
  56.         // private
  57.         doRemove = function(){
  58.             var ret;
  59.             if (win.removeEventListener) {
  60.                 ret = function (el, eventName, fn, capture) {
  61.                     if (eventName == 'mouseenter') {
  62.                         eventName = MOUSEOVER;
  63.                     } else if (eventName == 'mouseleave') {
  64.                         eventName = MOUSEOUT;
  65.                     }
  66.                     el.removeEventListener(eventName, fn, (capture));
  67.                 };
  68.             } else if (win.detachEvent) {
  69.                 ret = function (el, eventName, fn) {
  70.                     el.detachEvent("on" + eventName, fn);
  71.                 };
  72.             } else {
  73.                 ret = function(){};
  74.             }
  75.             return ret;
  76.         }();
  77.     function checkRelatedTarget(e) {
  78.         return !elContains(e.currentTarget, pub.getRelatedTarget(e));
  79.     }
  80.     function elContains(parent, child) {
  81.        if(parent && parent.firstChild){
  82.          while(child) {
  83.             if(child === parent) {
  84.                 return true;
  85.             }
  86.             child = child.parentNode;
  87.             if(child && (child.nodeType != 1)) {
  88.                 child = null;
  89.             }
  90.           }
  91.         }
  92.         return false;
  93.     }
  94.     // private
  95.     function _tryPreloadAttach() {
  96.         var ret = false,
  97.             notAvail = [],
  98.             element, i, len, v,
  99.             tryAgain = !loadComplete || (retryCount > 0);
  100.         if (!locked) {
  101.             locked = true;
  102.             for (i = 0, len = onAvailStack.length; i < len; i++) {
  103.                 v = onAvailStack[i];
  104.                 if(v && (element = doc.getElementById(v.id))){
  105.                     if(!v.checkReady || loadComplete || element.nextSibling || (doc && doc.body)) {
  106.                         element = v.override ? (v.override === true ? v.obj : v.override) : element;
  107.                         v.fn.call(element, v.obj);
  108.                         v = null;
  109.                     } else {
  110.                         notAvail.push(v);
  111.                     }
  112.                 }
  113.             }
  114.             retryCount = (notAvail.length === 0) ? 0 : retryCount - 1;
  115.             if (tryAgain) {
  116.                 startInterval();
  117.             } else {
  118.                 clearInterval(_interval);
  119.                 _interval = null;
  120.             }
  121.             ret = !(locked = false);
  122.         }
  123.         return ret;
  124.     }
  125.     // private
  126.     function startInterval() {
  127.         if(!_interval){
  128.             var callback = function() {
  129.                 _tryPreloadAttach();
  130.             };
  131.             _interval = setInterval(callback, POLL_INTERVAL);
  132.         }
  133.     }
  134.     // private
  135.     function getScroll() {
  136.         var dd = doc.documentElement,
  137.             db = doc.body;
  138.         if(dd && (dd[SCROLLTOP] || dd[SCROLLLEFT])){
  139.             return [dd[SCROLLLEFT], dd[SCROLLTOP]];
  140.         }else if(db){
  141.             return [db[SCROLLLEFT], db[SCROLLTOP]];
  142.         }else{
  143.             return [0, 0];
  144.         }
  145.     }
  146.     // private
  147.     function getPageCoord (ev, xy) {
  148.         ev = ev.browserEvent || ev;
  149.         var coord  = ev['page' + xy];
  150.         if (!coord && coord !== 0) {
  151.             coord = ev['client' + xy] || 0;
  152.             if (Ext.isIE) {
  153.                 coord += getScroll()[xy == "X" ? 0 : 1];
  154.             }
  155.         }
  156.         return coord;
  157.     }
  158.     var pub =  {
  159.         extAdapter: true,
  160.         onAvailable : function(p_id, p_fn, p_obj, p_override) {
  161.             onAvailStack.push({
  162.                 id:         p_id,
  163.                 fn:         p_fn,
  164.                 obj:        p_obj,
  165.                 override:   p_override,
  166.                 checkReady: false });
  167.             retryCount = POLL_RETRYS;
  168.             startInterval();
  169.         },
  170.         // This function should ALWAYS be called from Ext.EventManager
  171.         addListener: function(el, eventName, fn) {
  172.             el = Ext.getDom(el);
  173.             if (el && fn) {
  174.                 if (eventName == UNLOAD) {
  175.                     if (unloadListeners[el.id] === undefined) {
  176.                         unloadListeners[el.id] = [];
  177.                     }
  178.                     unloadListeners[el.id].push([eventName, fn]);
  179.                     return fn;
  180.                 }
  181.                 return doAdd(el, eventName, fn, false);
  182.             }
  183.             return false;
  184.         },
  185.         // This function should ALWAYS be called from Ext.EventManager
  186.         removeListener: function(el, eventName, fn) {
  187.             el = Ext.getDom(el);
  188.             var i, len, li;
  189.             if (el && fn) {
  190.                 if (eventName == UNLOAD) {
  191.                     if (unloadListeners[id] !== undefined) {
  192.                         for (i = 0, len = unloadListeners[id].length; i < len; i++) {
  193.                             li = unloadListeners[id][i];
  194.                             if (li && li[TYPE] == eventName && li[FN] == fn) {
  195.                                 unloadListeners[id].splice(i, 1);
  196.                             }
  197.                         }
  198.                     }
  199.                     return;
  200.                 }
  201.                 doRemove(el, eventName, fn, false);
  202.             }
  203.         },
  204.         getTarget : function(ev) {
  205.             ev = ev.browserEvent || ev;
  206.             return this.resolveTextNode(ev.target || ev.srcElement);
  207.         },
  208.         resolveTextNode : Ext.isGecko ? function(node){
  209.             if(!node){
  210.                 return;
  211.             }
  212.             // work around firefox bug, https://bugzilla.mozilla.org/show_bug.cgi?id=101197
  213.             var s = HTMLElement.prototype.toString.call(node);
  214.             if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
  215.                 return;
  216.             }
  217.             return node.nodeType == 3 ? node.parentNode : node;
  218.         } : function(node){
  219.             return node && node.nodeType == 3 ? node.parentNode : node;
  220.         },
  221.         getRelatedTarget : function(ev) {
  222.             ev = ev.browserEvent || ev;
  223.             return this.resolveTextNode(ev.relatedTarget ||
  224.                     (ev.type == MOUSEOUT ? ev.toElement :
  225.                      ev.type == MOUSEOVER ? ev.fromElement : null));
  226.         },
  227.         getPageX : function(ev) {
  228.             return getPageCoord(ev, "X");
  229.         },
  230.         getPageY : function(ev) {
  231.             return getPageCoord(ev, "Y");
  232.         },
  233.         getXY : function(ev) {
  234.             return [this.getPageX(ev), this.getPageY(ev)];
  235.         },
  236.         stopEvent : function(ev) {
  237.             this.stopPropagation(ev);
  238.             this.preventDefault(ev);
  239.         },
  240.         stopPropagation : function(ev) {
  241.             ev = ev.browserEvent || ev;
  242.             if (ev.stopPropagation) {
  243.                 ev.stopPropagation();
  244.             } else {
  245.                 ev.cancelBubble = true;
  246.             }
  247.         },
  248.         preventDefault : function(ev) {
  249.             ev = ev.browserEvent || ev;
  250.             if (ev.preventDefault) {
  251.                 ev.preventDefault();
  252.             } else {
  253.                 ev.returnValue = false;
  254.             }
  255.         },
  256.         getEvent : function(e) {
  257.             e = e || win.event;
  258.             if (!e) {
  259.                 var c = this.getEvent.caller;
  260.                 while (c) {
  261.                     e = c.arguments[0];
  262.                     if (e && Event == e.constructor) {
  263.                         break;
  264.                     }
  265.                     c = c.caller;
  266.                 }
  267.             }
  268.             return e;
  269.         },
  270.         getCharCode : function(ev) {
  271.             ev = ev.browserEvent || ev;
  272.             return ev.charCode || ev.keyCode || 0;
  273.         },
  274.         //clearCache: function() {},
  275.         // deprecated, call from EventManager
  276.         getListeners : function(el, eventName) {
  277.             Ext.EventManager.getListeners(el, eventName);
  278.         },
  279.         // deprecated, call from EventManager
  280.         purgeElement : function(el, recurse, eventName) {
  281.             Ext.EventManager.purgeElement(el, recurse, eventName);
  282.         },
  283.         _load : function(e) {
  284.             loadComplete = true;
  285.             var EU = Ext.lib.Event;
  286.             if (Ext.isIE && e !== true) {
  287.         // IE8 complains that _load is null or not an object
  288.         // so lets remove self via arguments.callee
  289.                 doRemove(win, "load", arguments.callee);
  290.             }
  291.         },
  292.         _unload : function(e) {
  293.              var EU = Ext.lib.Event,
  294.                 i, j, l, v, ul, id, len, index, scope;
  295.             for (id in unloadListeners) {
  296.                 ul = unloadListeners[id];
  297.                 for (i = 0, len = ul.length; i < len; i++) {
  298.                     v = ul[i];
  299.                     if (v) {
  300.                         try{
  301.                             scope = v[ADJ_SCOPE] ? (v[ADJ_SCOPE] === true ? v[OBJ] : v[ADJ_SCOPE]) :  win;
  302.                             v[FN].call(scope, EU.getEvent(e), v[OBJ]);
  303.                         }catch(ex){}
  304.                     }
  305.                 }
  306.             };
  307.             unloadListeners = null;
  308.             Ext.EventManager._unload();
  309.             doRemove(win, UNLOAD, EU._unload);
  310.         }
  311.     };
  312.     // Initialize stuff.
  313.     pub.on = pub.addListener;
  314.     pub.un = pub.removeListener;
  315.     if (doc && doc.body) {
  316.         pub._load(true);
  317.     } else {
  318.         doAdd(win, "load", pub._load);
  319.     }
  320.     doAdd(win, UNLOAD, pub._unload);
  321.     _tryPreloadAttach();
  322.     return pub;
  323. }();