zoukankan      html  css  js  c++  java
  • Event 系列: jquery event 源码

    1. /*  
    2.  * author:prk  
    3.  * date:2008-08-17  
    4.  * comment:analyse of jquery event  
    5.  *   
    6.  */  
    7. jQuery.event = {   
    8.   
    9.     // add 事件到一个元素上。   
    10.     add : function(elem, types, handler, data) {   
    11.         if (elem.nodeType == 3 || elem.nodeType == 8)// 空白节点或注释   
    12.             return;   
    13.   
    14.         // IE不能传入window,先复制一下。   
    15.         if (jQuery.browser.msie && elem.setInterval)   
    16.             elem = window;   
    17.   
    18.         // 为handler分配一个全局唯一的Id   
    19.         if (!handler.guid)   
    20.             handler.guid = this.guid++;   
    21.   
    22.         // 把data附到handler.data中   
    23.         if (data != undefined) {   
    24.             var fn = handler;   
    25.             handler = this.proxy(fn, function() {// 唯一Id,wrap原始handler Fn   
    26.                         return fn.apply(this, arguments);   
    27.                     });   
    28.             handler.data = data;   
    29.         }   
    30.   
    31.         // 初始化元素的events。如果没有取到events中值,就初始化data: {}   
    32.         var events = jQuery.data(elem, "events")   
    33.                 || jQuery.data(elem, "events", {}),   
    34.         // 如果没有取到handle中值,就初始化data: function() {....}   
    35.         handle = jQuery.data(elem, "handle")   
    36.                 || jQuery.data(elem, "handle", function() {   
    37.                     // 处理一个触发器的第二个事件和当page已经unload之后调用一个事件。   
    38.                         if (typeof jQuery != "undefined"  
    39.                                 && !jQuery.event.triggered)   
    40.                             return jQuery.event.handle.apply(// arguments.callee.elem=handle.elem   
    41.                                     arguments.callee.elem, arguments);   
    42.                     });   
    43.         // 增加elem做为handle属性,防止IE由于没有本地Event而内存泄露。   
    44.         handle.elem = elem;   
    45.   
    46.         // 处理采用空格分隔多个事件名,如jQuery(...).bind("mouseover mouseout", fn);   
    47.         jQuery.each(types.split(/\s+/), function(index, type) {   
    48.             // 命名空间的事件,一般不会用到。   
    49.                 var parts = type.split(".");   
    50.                 type = parts[0];   
    51.                 handler.type = parts[1];   
    52.   
    53.                 // 捆绑到本元素type事件的所有处理函数   
    54.                 var handlers = events[type];   
    55.   
    56.                 if (!handlers) {// 没有找到处理函数列表就初始化事件队列   
    57.                     handlers = events[type] = {};   
    58.   
    59.                     // 如果type不是ready,或ready的setup执行返回false   
    60.                     if (!jQuery.event.special[type]   
    61.                             || jQuery.event.special[type].setup   
    62.                                     .call(elem, data) === false) {   
    63.                         // 调用系统的事件函数来注册事件   
    64.                         if (elem.addEventListener)// FF   
    65.                             elem.addEventListener(type, handle, false);   
    66.                         else if (elem.attachEvent)// IE   
    67.                             elem.attachEvent("on" + type, handle);   
    68.                     }   
    69.                 }   
    70.   
    71.                 // 把处理器的id和handler形式属性对的形式保存在handlers列表中,   
    72.                 // 也存在events[type][handler.guid]中。   
    73.                 handlers[handler.guid] = handler;   
    74.   
    75.                 // 全局缓存这个事件的使用标识   
    76.                 jQuery.event.global[type] = true;   
    77.             });   
    78.   
    79.         // 防止IE内存泄露。   
    80.         elem = null;   
    81.     },   
    82.   
    83.     guid : 1,   
    84.     global : {},   
    85.   
    86.     // 从元素中remove一个事件   
    87.     remove : function(elem, types, handler) {   
    88.         if (elem.nodeType == 3 || elem.nodeType == 8)   
    89.             return;   
    90.         // 取出元素的events中Fn列表   
    91.         var events = jQuery.data(elem, "events"), ret, index;   
    92.   
    93.         if (events) {   
    94.             // remove所有的该元素的事件 .是命名空间的处理   
    95.             if (types == undefined   
    96.                     || (typeof types == "string" && types.charAt(0) == "."))   
    97.                 for (var type in events)   
    98.                     this.remove(elem, type + (types || ""));   
    99.             else {   
    100.                 // types, handler参数采用{type:xxx,handler:yyy}形式   
    101.                 if (types.type) {   
    102.                     handler = types.handler;   
    103.                     types = types.type;   
    104.                 }   
    105.   
    106.                 // 处理采用空格分隔多个事件名 jQuery(...).unbind("mouseover mouseout", fn);   
    107.                 jQuery   
    108.                         .each(types.split(/\s+/), function(index, type) {   
    109.                             // 命名空间的事件,一般不会用到。   
    110.                                 var parts = type.split(".");   
    111.                                 type = parts[0];   
    112.   
    113.                                 if (events[type]) {// 事件名找到   
    114.                                     if (handler)// handler传入,就remove事件名的这个处理函数   
    115.                                         delete events[type][handler.guid];//guid的作用   
    116.                                     else    // remove这个事件的所有处理函数,带有命名空间的处理   
    117.                                         for (handler in events[type])   
    118.                                             if (!parts[1]   
    119.                                                     || events[type][handler].type == parts[1])   
    120.                                                 delete events[type][handler];   
    121.   
    122.                                     // 如果没有该事件的处理函数存在,就remove事件名   
    123.                                     for (ret in events[type])// 看看有没有?   
    124.                                         break;   
    125.                                     if (!ret) {// 没有   
    126.                                         if (!jQuery.event.special[type]//不是ready   
    127.                                                 || jQuery.event.special[type].teardown   
    128.                                                         .call(elem) === false) {// type不等于ready   
    129.                                             if (elem.removeEventListener)// 在浏览器中remove事件名   
    130.                                                 elem.removeEventListener(type,   
    131.                                                         jQuery.data(elem,   
    132.                                                                 "handle"),   
    133.                                                         false);   
    134.                                             else if (elem.detachEvent)   
    135.                                                 elem.detachEvent("on" + type,   
    136.                                                         jQuery.data(elem,   
    137.                                                                 "handle"));   
    138.                                         }   
    139.                                         ret = null;   
    140.                                         delete events[type];// 在缓存中除去。   
    141.                                     }   
    142.                                 }   
    143.                             });   
    144.             }   
    145.   
    146.             // 不再使用,除去expando   
    147.             for (ret in events)   
    148.                 break;   
    149.             if (!ret) {   
    150.                 var handle = jQuery.data(elem, "handle");   
    151.                 if (handle)   
    152.                     handle.elem = null;   
    153.                 jQuery.removeData(elem, "events");   
    154.                 jQuery.removeData(elem, "handle");   
    155.             }   
    156.         }   
    157.     },   
    158.   
    159.     trigger : function(type, data, elem, donative, extra) {   
    160.         data = jQuery.makeArray(data);   
    161.   
    162.         if (type.indexOf("!") >= 0) {// 支持!的not的操作如!click,除click之后的所有   
    163.             type = type.slice(0, -1);// 除最后一个字符?   
    164.             var exclusive = true;   
    165.         }   
    166.   
    167.         if (!elem) {// 处理全局的fire事件   
    168.             if (this.global[type])   
    169.                 jQuery.each(jQuery.cache, function() {   
    170.                     // 从cache中找到所有注册该事件的元素,触发改事件的处理函数   
    171.                         if (this.events && this.events[type])   
    172.                             jQuery.event.trigger(type, data, this.handle.elem);   
    173.                     });   
    174.         } else {// 处理单个元素事件的fire事件   
    175.             if (elem.nodeType == 3 || elem.nodeType == 8)   
    176.                 return undefined;   
    177.   
    178.             var val, ret, fn = jQuery.isFunction(elem[type] || null),   
    179.             // 我们是否要提交一个伪造的事件?   
    180.             event = !data[0] || !data[0].preventDefault;   
    181.   
    182.             // 构建伪造的事件。   
    183.             if (event) {   
    184.                 data.unshift( {//存到数组中的第一个   
    185.                     type : type,   
    186.                     target : elem,   
    187.                     preventDefault : function() {   
    188.                     },   
    189.                     stopPropagation : function() {   
    190.                     },   
    191.                     timeStamp : now()   
    192.                 });   
    193.                 data[0][expando] = true// 不需要修正伪造事件   
    194.             }   
    195.   
    196.             //防止事件名出错   
    197.             data[0].type = type;   
    198.             if (exclusive)   
    199.                 data[0].exclusive = true;   
    200.   
    201.             // 触发事件   
    202.             var handle = jQuery.data(elem, "handle");   
    203.             if (handle)   
    204.                 val = handle.apply(elem, data);   
    205.   
    206.             // Handle triggering native .onfoo handlers (and on links since we   
    207.             // don't call .click() for links)   
    208.             //处理触发.onfoo这样的本地处理方法,但是是对于links 's .click()不触发   
    209.             if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click"))   
    210.                     && elem["on" + type]&& elem["on" + type].apply(elem, data) === false)   
    211.                 val = false;   
    212.   
    213.             // Extra functions don't get the custom event object   
    214.             if (event)   
    215.                 data.shift();   
    216.   
    217.             // 处理触发extra事件   
    218.             if (extra && jQuery.isFunction(extra)) {   
    219.                 //执行extra,同时把结果存到data中。   
    220.                 ret = extra.apply(elem, val == null ? data : data.concat(val));   
    221.                 // if anything is returned, give it precedence and have it   
    222.                 // overwrite the previous value   
    223.                 if (ret !== undefined)   
    224.                     val = ret;   
    225.             }   
    226.   
    227.             // 触发本地事件   
    228.             if (fn && donative !== false && val !== false  
    229.                     && !(jQuery.nodeName(elem, 'a') && type == "click")) {   
    230.                 this.triggered = true;   
    231.                 try {   
    232.                     elem[type]();   
    233.                     //对于一些hidden的元素,IE会报错   
    234.                 } catch (e) {   
    235.                 }   
    236.             }   
    237.   
    238.             this.triggered = false;   
    239.         }   
    240.   
    241.         return val;   
    242.     },   
    243.   
    244.     handle : function(event) {   
    245.         // 返回 undefined or false   
    246.         var val, ret, namespace, all, handlers;   
    247.   
    248.         event = arguments[0] = jQuery.event.fix(event || window.event);   
    249.   
    250.         // 命名空间处理   
    251.         namespace = event.type.split(".");   
    252.         event.type = namespace[0];   
    253.         namespace = namespace[1];   
    254.         // all = true 表明任何 handler   
    255.         all = !namespace && !event.exclusive;   
    256.         // 找到元素的events中缓存的事件名的处理函数列表   
    257.         handlers = (jQuery.data(this"events") || {})[event.type];   
    258.   
    259.         for (var j in handlers) {// 每个处理函数执行   
    260.             var handler = handlers[j];   
    261.   
    262.             // Filter the functions by class   
    263.             if (all || handler.type == namespace) {   
    264.                 // 传入引用,为了之后删除它们   
    265.                 event.handler = handler;   
    266.                 event.data = handler.data;   
    267.   
    268.                 ret = handler.apply(this, arguments);// 执行事件处理函数   
    269.   
    270.                 if (val !== false)   
    271.                     val = ret;// 只要有一个处理函数返回false,本函数就返回false.   
    272.   
    273.                 if (ret === false) {// 不执行浏览器默认的动作   
    274.                     event.preventDefault();   
    275.                     event.stopPropagation();   
    276.                 }   
    277.             }   
    278.         }   
    279.   
    280.         return val;   
    281.     },   
    282.   
    283.     props : "altKey attrChange attrName bubbles button cancelable charCode clientX "  
    284.             + "clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode "  
    285.             + "metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX "  
    286.             + "screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which"  
    287.                     .split(" "),   
    288.   
    289.     //对事件进行包裹。   
    290.     fix : function(event) {   
    291.         if (event[expando] == true)//表明事件已经包裹过   
    292.             return event;   
    293.   
    294.         //保存原始event,同时clone一个。   
    295.         var originalEvent = event;   
    296.         event = {   
    297.             originalEvent : originalEvent   
    298.         };   
    299.   
    300.         for (var i = this.props.length, prop;i;) {   
    301.             prop = this.props[--i];   
    302.             event[prop] = originalEvent[prop];   
    303.         }   
    304.            
    305.         event[expando] = true;   
    306.            
    307.         //加上preventDefault and stopPropagation,在clone不会运行   
    308.         event.preventDefault = function() {   
    309.             // 在原始事件上运行   
    310.             if (originalEvent.preventDefault)   
    311.                 originalEvent.preventDefault();   
    312.                
    313.             originalEvent.returnValue = false;   
    314.         };   
    315.         event.stopPropagation = function() {   
    316.             // 在原始事件上运行   
    317.             if (originalEvent.stopPropagation)   
    318.                 originalEvent.stopPropagation();   
    319.                
    320.             originalEvent.cancelBubble = true;   
    321.         };   
    322.   
    323.         // 修正 timeStamp   
    324.         event.timeStamp = event.timeStamp || now();   
    325.   
    326.         // 修正target   
    327.         if (!event.target)   
    328.             event.target = event.srcElement || document;               
    329.         if (event.target.nodeType == 3)//文本节点是父节点。   
    330.             event.target = event.target.parentNode;   
    331.   
    332.         // relatedTarget   
    333.         if (!event.relatedTarget && event.fromElement)   
    334.             event.relatedTarget = event.fromElement == event.target   
    335.                     ? event.toElement   
    336.                     : event.fromElement;   
    337.   
    338.         // Calculate pageX/Y if missing and clientX/Y available   
    339.         if (event.pageX == null && event.clientX != null) {   
    340.             var doc = document.documentElement, body = document.body;   
    341.             event.pageX = event.clientX   
    342.                     + (doc && doc.scrollLeft || body && body.scrollLeft || 0)   
    343.                     - (doc.clientLeft || 0);   
    344.             event.pageY = event.clientY   
    345.                     + (doc && doc.scrollTop || body && body.scrollTop || 0)   
    346.                     - (doc.clientTop || 0);   
    347.         }   
    348.   
    349.         // Add which for key events   
    350.         if (!event.which   
    351.                 && ((event.charCode || event.charCode === 0)   
    352.                         ? event.charCode   
    353.                         : event.keyCode))   
    354.             event.which = event.charCode || event.keyCode;   
    355.   
    356.         // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)   
    357.         if (!event.metaKey && event.ctrlKey)   
    358.             event.metaKey = event.ctrlKey;   
    359.   
    360.         // Add which for click: 1 == left; 2 == middle; 3 == right   
    361.         // Note: button is not normalized, so don't use it   
    362.         if (!event.which && event.button)   
    363.             event.which = (event.button & 1 ? 1 : (event.button & 2  
    364.                     ? 3  
    365.                     : (event.button & 4 ? 2 : 0)));   
    366.   
    367.         return event;   
    368.     },   
    369.   
    370.     proxy : function(fn, proxy) {   
    371.         // 作用就是分配全局guid.   
    372.         proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;   
    373.         return proxy;   
    374.     },   
    375.   
    376.     special : {   
    377.         ready : {   
    378.             // Make sure the ready event is setup   
    379.             setup : bindReady,   
    380.             teardown : function() {   
    381.             }   
    382.         }   
    383.     }   
    384. };   
    385.   
    386. if (!jQuery.browser.msie) {   
    387.     // Checks if an event happened on an element within another element   
    388.     // Used in jQuery.event.special.mouseenter and mouseleave handlers   
    389.     var withinElement = function(event) {   
    390.         // Check if mouse(over|out) are still within the same parent element   
    391.         var parent = event.relatedTarget;   
    392.         // Traverse up the tree   
    393.         while (parent && parent != this)   
    394.             try {   
    395.                 parent = parent.parentNode;   
    396.             } catch (e) {   
    397.                 parent = this;   
    398.             }   
    399.   
    400.         if (parent != this) {   
    401.             // set the correct event type   
    402.             event.type = event.data;   
    403.             // handle event if we actually just moused on to a non sub-element   
    404.             jQuery.event.handle.apply(this, arguments);   
    405.         }   
    406.     };   
    407.   
    408.     jQuery.each( {   
    409.         mouseover : 'mouseenter',   
    410.         mouseout : 'mouseleave'  
    411.     }, function(orig, fix) {   
    412.         jQuery.event.special[fix] = {   
    413.             setup : function() {   
    414.                 jQuery.event.add(this, orig, withinElement, fix);   
    415.             },   
    416.             teardown : function() {   
    417.                 jQuery.event.remove(this, orig, withinElement);   
    418.             }   
    419.         };   
    420.     });   
    421. }   
    422.   
    423. jQuery.fn.extend( {   
    424.     bind : function(type, data, fn) {   
    425.         return type == "unload" ? this.one(type, data, fn) : this  
    426.                 .each(function() {// fn || data, fn && data实现了data参数可有可无   
    427.                     jQuery.event.add(this, type, fn || data, fn && data);   
    428.                 });   
    429.     },   
    430.   
    431.         // 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数。   
    432.         // 在每个对象上,这个事件处理函数只会被执行一次。其他规则与bind()函数相同。   
    433.         // 这个事件处理函数会接收到一个事件对象,可以通过它来阻止(浏览器)默认的行为。   
    434.         // 如果既想取消默认的行为,又想阻止事件起泡,这个事件处理函数必须返回false。   
    435.         one : function(type, data, fn) {   
    436.             var one = jQuery.event.proxy(fn || data, function(event) {   
    437.                 jQuery(this).unbind(event, one);   
    438.                 return (fn || data).apply(this, arguments);// this-->当前的元素   
    439.                 });   
    440.             return this.each(function() {   
    441.                 jQuery.event.add(this, type, one, fn && data);   
    442.             });   
    443.         },   
    444.   
    445.         // bind()的反向操作,从每一个匹配的元素中删除绑定的事件。   
    446.         // 如果没有参数,则删除所有绑定的事件。   
    447.         // 你可以将你用bind()注册的自定义事件取消绑定。   
    448.         // I如果提供了事件类型作为参数,则只删除该类型的绑定事件。   
    449.         // 如果把在绑定时传递的处理函数作为第二个参数,则只有这个特定的事件处理函数会被删除。   
    450.         unbind : function(type, fn) {   
    451.             return this.each(function() {   
    452.                 jQuery.event.remove(this, type, fn);   
    453.             });   
    454.         },   
    455.   
    456.        
    457.         trigger : function(type, data, fn) {   
    458.             return this.each(function() {   
    459.                 jQuery.event.trigger(type, data, thistrue, fn);   
    460.             });   
    461.         },   
    462.         //这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作.   
    463.         triggerHandler : function(type, data, fn) {   
    464.             return this[0]   
    465.                     && jQuery.event.trigger(type, data, this[0], false, fn);   
    466.         },   
    467.            
    468.         //每次点击后依次调用函数。   
    469.         toggle : function(fn) {        
    470.             var args = arguments, i = 1;   
    471.                
    472.             while (i < args.length)//每个函数分配GUID   
    473.                 jQuery.event.proxy(fn, args[i++]);   
    474.   
    475.             return this.click(jQuery.event   
    476.                     .proxy(fn, function(event) {//分配GUID                       
    477.                             this.lastToggle = (this.lastToggle || 0) % i;//上一个函数                               
    478.                             event.preventDefault();//阻止缺省动作   
    479.                             //执行参数中的第几个函数,apply可以采用array-like的参数   
    480.                             //With apply, you can use an array literal,    
    481.                             //for example, fun.apply(this, [name, value]),   
    482.                             //or an Array object, for example, fun.apply(this, new Array(name, value)).    
    483.                             return args[this.lastToggle++].apply(this,   
    484.                                     arguments) || false;   
    485.                         }));   
    486.         },   
    487.            
    488.         //一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法。   
    489.         //这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态。   
    490.         //当鼠标移动到一个匹配的元素上面时,会触发指定的第一个函数。当鼠标移出这个元素时,   
    491.         //会触发指定的第二个函数。而且,会伴随着对鼠标是否仍然处在特定元素中的检测(例如,处在div中的图像),   
    492.         //如果是,则会继续保持“悬停”状态,而不触发移出事件(修正了使用mouseout事件的一个常见错误)。   
    493.         hover : function(fnOver, fnOut) {   
    494.             return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);   
    495.         },   
    496.            
    497.         //dom ready时执行 fn   
    498.         ready : function(fn) {             
    499.             bindReady();//注册监听             
    500.             if (jQuery.isReady)//ready就运行                  
    501.                 fn.call(document, jQuery);             
    502.             else  
    503.                 // 增加这个函数到queue中。可见支持无数的ready的调用。   
    504.                 jQuery.readyList.push(function() {   
    505.                     return fn.call(this, jQuery);   
    506.                 });   
    507.   
    508.             return this;   
    509.         }   
    510.     });   
    511.   
    512. jQuery.extend( {   
    513.     isReady : false,   
    514.     readyList : [],   
    515.     // Handle when the DOM is ready   
    516.         ready : function() {               
    517.             if (!jQuery.isReady) {         
    518.                 jQuery.isReady = true;   
    519.                    
    520.                 if (jQuery.readyList) {                    
    521.                     jQuery.each(jQuery.readyList, function() {   
    522.                         this.call(document);   
    523.                     });                
    524.                     jQuery.readyList = null;   
    525.                 }   
    526.                    
    527.                 jQuery(document).triggerHandler("ready");   
    528.             }   
    529.         }   
    530.     });   
    531.   
    532. var readyBound = false;   
    533.   
    534. function bindReady() {   
    535.     if (readyBound)   
    536.         return;   
    537.     readyBound = true;   
    538.   
    539.     // Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件       
    540.     if (document.addEventListener && !jQuery.browser.opera)   
    541.         //当DOMContentLoaded事件触发时就运行jQuery.ready   
    542.         document.addEventListener("DOMContentLoaded", jQuery.ready, false);   
    543.   
    544.     //IE或不是frame的window   
    545.     if (jQuery.browser.msie && window == top)   
    546.         (function() {   
    547.             if (jQuery.isReady)   
    548.                 return;   
    549.             try {   
    550.                 // 在ondocumentready之前,一直都会抛出异常                 
    551.                 // http://javascript.nwbox.com/IEContentLoaded/   
    552.                 document.documentElement.doScroll("left");   
    553.             } catch (error) {   
    554.                 //一直运行bindReady()(=arguments.callee)   
    555.                 setTimeout(arguments.callee, 0);   
    556.                 return;   
    557.             }              
    558.             jQuery.ready();//documentready就运行jQuery.ready   
    559.         })();   
    560.   
    561.     if (jQuery.browser.opera)   
    562.         document.addEventListener("DOMContentLoaded", function() {   
    563.             if (jQuery.isReady)   
    564.                 return;   
    565.                 //只有styleSheets完全enable时,才是完全的load,其实还有pic   
    566.             for (var i = 0;i < document.styleSheets.length; i++)   
    567.                 if (document.styleSheets[i].disabled) {//通过styleSheets来判断   
    568.                     setTimeout(arguments.callee, 0);   
    569.                     return;   
    570.                 }              
    571.                 jQuery.ready();   
    572.             }, false);   
    573.   
    574.     if (jQuery.browser.safari) {   
    575.         var numStyles;   
    576.         (function() {   
    577.             if (jQuery.isReady)   
    578.                 return;   
    579.                 //首先得得到readyState=loaded或=complete   
    580.             if (document.readyState != "loaded"  
    581.                     && document.readyState != "complete") {   
    582.                 setTimeout(arguments.callee, 0);   
    583.                 return;   
    584.             }   
    585.             //取得style的length,比较它们之间的长度,看看是不是完成loaded   
    586.             if (numStyles === undefined)   
    587.                 numStyles = jQuery("style, link[rel=stylesheet]").length;   
    588.             if (document.styleSheets.length != numStyles) {   
    589.                 setTimeout(arguments.callee, 0);   
    590.                 return;   
    591.             }              
    592.             jQuery.ready();   
    593.         })();   
    594.     }   
    595.   
    596.     //最后只能依赖于window.load.   
    597.     jQuery.event.add(window, "load", jQuery.ready);   
    598. }   
    599.   
    600. //为jquery对象增加常用的事件方法   
    601. jQuery   
    602.         .each(   
    603.                 ("blur,focus,load,resize,scroll,unload,click,dblclick,"  
    604.                         + "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + "submit,keydown,keypress,keyup,error")   
    605.                         .split(","), function(i, name) {                       
    606.                 jQuery.fn[name] = function(fn) {   
    607.                     return fn ? this.bind(name, fn) : this.trigger(name);   
    608.                 };   
    609.             });   
    610.   
    611. // Prevent memory leaks in IE   
    612. // And prevent errors on refresh with events like mouseover in other browsers   
    613. // Window isn't included so as not to unbind existing unload events   
    614. jQuery(window).bind('unload', function() {   
    615.     for (var id in jQuery.cache)   
    616.         // Skip the window   
    617.         if (id != 1 && jQuery.cache[id].handle)   
    618.             jQuery.event.remove(jQuery.cache[id].handle.elem);   
    619. });  
  • 相关阅读:
    输出1到100内前五个可以被3整除的数 while for
    Java:运用while()与do....while与for()
    break & continue
    while循环
    for循环例子
    if语句条件
    上位机开发二----第一个程序hallo world
    c语言获取数组长度的三种方法
    halcon标定后畸变校正与测量
    海康相机SDK联合c++标定
  • 原文地址:https://www.cnblogs.com/rooney/p/1346132.html
Copyright © 2011-2022 走看看