This module is used to block browser differences of DOM events and provides powerful event proxy mechanisms (delegate, undelegate, live, die ):
// ================================================ ====/// Event module by situ zhengmei 2011.8.21 // ======================== ===================== (function (global, doc) {var dom = global [Doc. URL. replace (/(#. + | \ W)/g, '')]; Dom. define ("Event", "emitter, Travel", function () {Dom. log ("load Dom. event module succeeded ") var types =" contextmenu, click, dblclick, mouseout, Mouseover, mouseenter, mouseleave, mousemove, mousedown, mouseup, mousewheel, "+" abort, error, l Oad, unload, resize, scroll, change, input, select, reset, submit, "+" Blur, focus, focusin, focusout, "+" keypress, keydown, keyup "; dom. eventsupport = function (eventname, El) {El = El | Doc. createelement ("Div"); eventname = "on" + eventname; var ret = eventname in El; If (El. setattribute &&! RET) {el. setattribute (eventname, "Return;"); ret = typeof El [eventname] = "function";} el = NULL; return ret ;}; var events = Dom. events, specials = events. special, rword = Dom. rword; // used to simulate mouseenter and mouseleave in a standard browser. // currently, in addition to the IE series, mouseenter/mouseleave/focusin/focusout are supported. // opera11 also supports these four events, they also become W3C dom3 event specifications // see http://www.filehippo.com/pl/download_opera/changelog/9476/ // http://dev.w3.org /2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html var brokenmouseenter =! Dom. eventsupport ("mouseenter"); "mouseenter_mouseover, mouseleave_mouseout ". replace (rword, function (types) {types = types. split ("_"); var OBJ = specials [types [0] = {setup: function (target) {Dom. BIND (target, types [1], function () {OBJ [UUID (target) + "_ HANDLE"] = arguments. callee; E = events. fix (E); var parent = E. relatedtarget; try {While (parent & parent! = Target) {parent = parent. parentnode;} If (parent! = Target) {e. type = types [0]; events. handle. call (target, e) ;}} catch (e) {};}, teardown: function (target) {events. teardown (target, types [1], OBJ [UUID (target) + "_ HANDLE"]); Delete OBJ [UUID (target) + "_ HANDLE"]}; OBJ. livesetup = obj. setup; obj. liveteardown = obj. teardown; If (! Brokenmouseenter) {Delete obj. setup; Delete obj. teardown ;}}); If (! Dom. eventsupport ("focusin") {"focusin_focus, focusout_blur ". replace (rword, function (types) {types = types. split ("_"); var attaches = 0; function handler (e) {events.fire(e.tar get, types [0]);} specials [types [0] = {type: types [1], setup: function () {If (attaches ++ = 0) {Doc. addeventlistener (types [1], handler, true) ;}}, teardown: function () {If (-- attaches === 0) {Doc. removeeventlisten Er (types [1], handler, true) ;}}}); // http://www.w3help.org/zh-cn/causes/SD9013 // https://prototype.lighthouseapp.com/projects/8886/tickets/697-eventfire-to-support-all-events-not-only-custom-ones // http://www.quirksmode.org/dom/events/scroll.html if (! Dom. eventsupport ("mousewheel") {specials. mousewheel = {type: "dommousescroll" // FF }}// obtain the uniqueid function UUID (target) {return Dom of the event sender. data (target, "UUID")} // bubble situation of the submit event ---- IE6-9: form; FF: Document; chrome: window; Safari: window; Opera: window if (! Dom. eventsupport ("Submit ")&&! Doc. dispatchevent) {var submitcode = Dom. oneobject ("13,108"); var submitbutton = Dom. oneobject ("Submit, image"); var submitinput = Dom. oneobject ("text, password, textarea"); var submitroom = specials. submit = {livesetup: function (target) {// Save the Event Callback Function to a place that can be found during uninstallation. submitroom [UUID (target) + "_ HANDLE"] = function () {var E = events. fix (event), El = e.tar get, type = el. type; If (El. form & (submitbutton [Type] | submitcode [E. which] & submitinput [type]) {Dom. log ("Submit event bubbling under simulation ie"); E. type = "Submit"; events. handle. call (target, e) ;}} "onclick, onkeypress ". replace (rword, function (type) {target. attachevent (type, submitroom [UUID (target) + "_ HANDLE"]) ;}, liveteardown: function (target) {"onclick, onkeypress ". replace (rword, function (type) {target. detachevent (type, submitroom [UUID (target) + "_ handl E "] | Dom. noop) ;}); Delete submitroom [UUID (target) + "_ HANDLE"] ;}}// bubble of reset events ---- ff and opera can bubble to document, other browsers can only go to form if (! Dom. eventsupport ("reset") {var resetroom = specials. Reset = {livesetup: Doc. dispatchevent? 0: function (target) {resetroom [UUID (target) + "_ HANDLE"] = function () {var E = events. fix (event), El = e.tar get; If (El. form & (E. which = 27 | el. type = "reset") {Dom. log ("simulate reset event bubbling"); E. type = "reset"; events. handle. call (target, e) ;}} "onclick, onkeypress ". replace (rword, function (type) {target. attachevent (type, resetroom [UUID (target) + "_ HANDLE"]) ;}, liveteardown: Doc. dispatchevent? 0: function (target) {"onclick, onkeypress ". replace (rword, function (type) {target. dettachevent (type, resetroom [UUID (target) + "_ HANDLE"]) ;}) Delete resetroom [UUID (target) + "_ HANDLE"] ;}} // The bubble of the change event ---- ff and opera can bubble to the document. Other Browsers Do not bubble if (! Dom. eventsupport ("change") {function getval (node) {var type = node. type, val = node. value; If (type = "radio" | type = "checkbox") {val = node. checked;} else if (type = "select-multiple") {val = node. selectedindex =-1? "": Dom. lang (node. options ). map (function (node) {return node. selected ;}). join ("-");} else if (type = "select-one") {val = node. selectedindex;} return val;} function changehandle (e) {var etype = E. type, node = E. srcelement, ntype = node. type // if it is not a form element or is in read-only status, if (! Node. form | node. readonly) {return;} If (etype = "keydown") {var flag = false; If (E. keycode = 13 & ntype! = "Textarea") | (E. keycode = 32 & (ntype = "checkbox" | ntype = "radio") | ntype = "select-multiple ") {flag = true;} If (! Flag) {return ;}// obtain the previous data var olddata = Dom. data (node, "_ change_data"); // obtain the current data var newdata = getval (node); // If (etype! = "Focusout" | ntype! = "Radio") {Dom. data (node, "_ change_data", newdata);} If (newdata = undefined | newdata = olddata) {return;} If (olddata! = NULL | newdata) {e = events. fix (e); E. type = "change"; events. handle. call (node, e) ;}}var changoom = specials. change = {livesetup: function (node) {// This event is used to collect data node. attachevent ("onbeforeactivate", function () {changoom [UUID (node) + event. type + "_ handler"] = arguments. callee; Dom. data (node, "_ change_data", getval (node) ;}); // when you click the target element, the following events will occur in sequence: beforeactivate click | befored Eactivate focusout "onfocusout, onbeforedeactivate, onclick, onkeydown ". replace (rword, function (type) {node. attachevent (type, function () {changoom [UUID (node) + event. type + "_ handler"] = arguments. callee; changehandle. call (node, event) ;}) ;}, liveteardown: function (node) {var uid = UUID (node); "focusout, beforedeactivate, click, keydown, beforeactivate ". replace (rword, function (type) {node. detachevent ("On "+ Type, changoom [uid + Type +" _ handler "] | Dom. noop); Delete changoom [uid + Type + "_ handler"]}) ;}}// when an element, or when any element inside it gets the focus, this event is triggered. // This differs from the focus event in that it can detect the child element on the parent element to obtain the focus. // ======================================== Dom. include ({toggleclick: function (/* fn1, FN2, fn3 */) {var FNS = []. slice. call (arguments), I = 0; return this. click (function (e) {var fn = FNS [I ++] | FNS [I = 0, I ++]; fn. call (this, e) ;}, hover: function (fnover, fnout) {return this. mouseenter (fnover ). mouseleave (fnout | fnover) ;}}); "bind, unbind, fire ". replace (rword, function (method) {Dom. FN [Method] = Fu Nction () {var ARGs = arguments; return this. each (function (target) {events [Method]. apply (target, argS) ;};}); // The principle of event proxy is to bind the event listener to the top-level element, if the event source element is specific to the lower-layer bubble or captured event, the corresponding callback "delegate, undelegate" is executed ". replace (rword, function (method) {Dom. FN [Method] = function (expr, type, callback) {var special = events. special [type] | |{}; var bag = {live: expr, type: type, callback: callback} bag. UUID = callback. UUID = do M. UUID ++; // select an available event type. For example, if mouseenter is unavailable in a standard browser, you must use Mouseover to impersonate type = Special. type | type return this. each (function (node) {events [Method = "delegate "? "Bind": "Unbind"]. apply (node, [type, bag, true]) ;}}); "Live, die ". replace (rword, function (method) {Dom. FN [Method] = function (type, callback) {var expr = This. selector; var Doc = this.doc | Doc; If (! Expr) {expr = Dom. Noop;} return dom (DOC) [Method = "live "? "Delegate": "undelegate"] (expr, type, callback) ;}}); types. replace (rword, function (type) {Dom. FN [type] = function (callback, phase, trust) {return this. BIND (type, callback, phase, trust) ;}}); Specify parameter values (this,this.doc ument );
Related Links: Dom framework emitter module