📄 handler.js
字号:
/* * Handler.js -- Portable event handler registration functions * * This module defines event handler registration and deregistration functions * Handler.add() and Handler.remove(). Both functions take three arguments: * * element: the DOM element, document, or window on which the handler * is to be added or removed. * * eventType: a string that specifies the type of event for which the * handler is to be invoked. Use DOM-standard type names, which do * not include an "on" prefix. Examples: "click", "load", "mouseover". * * handler: The function to be invoked when an event of the specified type * occurs on the specified element. This function will be invoked as * a method of the element on which it is registered, and the "this" * keyword will refer to that element. The handler function will be * passed an event object as its sole argument. This event object will * either be a DOM-standard Event object or a simulated one. If a * simulated event object is passed, it will have the following DOM- * compliant properties: type, target, currentTarget, relatedTarget, * eventPhase, clientX, clientY, screenX, screenY, altKey, ctrlKey, * shiftKey, charCode, stopPropagation(), and preventDefault() * * Handler.add() and Handler.remove() have no return value. * * Handler.add() ignores duplicate registrations of the same handler for * the same event type and element. Handler.remove() does nothing if called * to remove a handler that has not been registered. * * Implementation notes: * * In browsers that support the DOM standard addEventListener() and * removeEventListener() event registration functions, Handler.add() and * Handler.remove() simply invoke these functions, passing false as the * third argument (meaning that the event handlers are never registered as * capturing event handlers). * * In versions of Internet Explorer that support attachEvent(), Handler.add() * and Handler.remove() use attachEvent() and detachEvent(). To * invoke the handler function with the correct this keyword, a closure is * used. Since closures of this sort cause memory leaks in Internet Explorer, * Handler.add() automatically registers an onunload handler to deregister * all event handlers when the page is unloaded. To keep track of * registered handlers, Handler.add() creates a property named _allHandlers on * the window object and creates a property named _handlers on any element on * which a handler is registered. */var Handler = {};// In DOM-compliant browsers, our functions are trivial wrappers around// addEventListener() and removeEventListener().if (document.addEventListener) { Handler.add = function(element, eventType, handler) { element.addEventListener(eventType, handler, false); }; Handler.remove = function(element, eventType, handler) { element.removeEventListener(eventType, handler, false); };}// In IE 5 and later, we use attachEvent() and detachEvent(), with a number of// hacks to make them compatible with addEventListener and removeEventListener.else if (document.attachEvent) { Handler.add = function(element, eventType, handler) { // Don't allow duplicate handler registrations // _find() is a private utility function defined below. if (Handler._find(element, eventType, handler) != -1) return; // To invoke the handler function as a method of the // element, we've got to define this nested function and register // it instead of the handler function itself. var wrappedHandler = function(e) { if (!e) e = window.event; // Create a synthetic event object with partial compatibility // with DOM events. var event = { _event: e, // In case we really want the IE event object type: e.type, // Event type target: e.srcElement, // Where the event happened currentTarget: element, // Where we're handling it relatedTarget: e.fromElement?e.fromElement:e.toElement, eventPhase: (e.srcElement==element)?2:3, // Mouse coordinates clientX: e.clientX, clientY: e.clientY, screenX: e.screenX, screenY: e.screenY, // Key state altKey: e.altKey, ctrlKey: e.ctrlKey, shiftKey: e.shiftKey, charCode: e.keyCode, // Event management functions stopPropagation: function() {this._event.cancelBubble = true;}, preventDefault: function() {this._event.returnValue = false;} } // Invoke the handler function as a method of the element, passing // the synthetic event object as its single argument. // Use Function.call() if defined; otherwise do a hack if (Function.prototype.call) handler.call(element, event); else { // If we don't have Function.call, fake it like this element._currentHandler = handler; element._currentHandler(event); element._currentHandler = null; } }; // Now register that nested function as our event handler. element.attachEvent("on" + eventType, wrappedHandler); // Now we must do some record keeping to associate the user-supplied // handler function and the nested function that invokes it. // We have to do this so that we can deregister the handler with the // remove() method and also deregister it automatically on page unload. // Store all info about this handler into an object var h = { element: element, eventType: eventType, handler: handler, wrappedHandler: wrappedHandler }; // Figure out what document this handler is part of. // If the element has no "document" property, it is not // a window or a document element, so it must be the document // object itself. var d = element.document || element; // Now get the window associated with that document var w = d.parentWindow; // We have to associate this handler with the window, // so we can remove it when the window is unloaded var id = Handler._uid(); // Generate a unique property name if (!w._allHandlers) w._allHandlers = {}; // Create object if needed w._allHandlers[id] = h; // Store the handler info in this object // And associate the id of the handler info with this element as well if (!element._handlers) element._handlers = []; element._handlers.push(id); // If there is not an onunload handler associated with the window, // register one now. if (!w._onunloadHandlerRegistered) { w._onunloadHandlerRegistered = true; w.attachEvent("onunload", Handler._removeAllHandlers); } }; Handler.remove = function(element, eventType, handler) { // Find this handler in the element._handlers[] array. var i = Handler._find(element, eventType, handler); if (i == -1) return; // If the handler was not registered, do nothing // Get the window of this element var d = element.document || element; var w = d.parentWindow; // Look up the unique id of this handler var handlerId = element._handlers[i]; // And use that to look up the handler info var h = w._allHandlers[handlerId]; // Using that info, we can detach the handler from the element element.detachEvent("on" + eventType, h.wrappedHandler); // Remove one element from the element._handlers array element._handlers.splice(i, 1); // And delete the handler info from the per-window _allHandlers object delete w._allHandlers[handlerId]; }; // A utility function to find a handler in the element._handlers array // Returns an array index or -1 if no matching handler is found Handler._find = function(element, eventType, handler) { var handlers = element._handlers; if (!handlers) return -1; // if no handlers registered, nothing found // Get the window of this element var d = element.document || element; var w = d.parentWindow; // Loop through the handlers associated with this element, looking // for one with the right type and function. // We loop backward because the most recently registered handler // is most likely to be the first removed one. for(var i = handlers.length-1; i >= 0; i--) { var handlerId = handlers[i]; // get handler id var h = w._allHandlers[handlerId]; // get handler info // If handler info matches type and handler function, we found it. if (h.eventType == eventType && h.handler == handler) return i; } return -1; // No match found }; Handler._removeAllHandlers = function() { // This function is registered as the onunload handler with // attachEvent. This means that the this keyword refers to the // window in which the event occurred. var w = this; // Iterate through all registered handlers for(id in w._allHandlers) { // Get handler info for this handler id var h = w._allHandlers[id]; // Use the info to detach the handler h.element.detachEvent("on" + h.eventType, h.wrappedHandler); // Delete the handler info from the window delete w._allHandlers[id]; } } // Private utility to generate unique handler ids Handler._counter = 0; Handler._uid = function() { return "h" + Handler._counter++; };}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -