JavaScript does not have its own event system. With the help of Dom's Event System, if Javascript objects are only involved, the system will stop. The following is a counterfeit product. Do not expect events to bubble up.
If (typeof array. Prototype. foreach! = "Function") {array. prototype. foreach = function (FN, scope) {for (VAR I = 0, n = This. length >>> 0; I <n; I ++) {I in this & FN. call (scope, this [I], I, this) }}var eventdispatcher = {$ A: function (iterable) {return array. prototype. slice. call (iterable)}, createevents: function () {This. _ listeners ={}; var names = This. events | [], name, type; names. foreach (function (type) {name = "on" + type. replace (/_ ([A-Z])/ G, function ($1, $2) {return $2. touppercase ()}). replace (/^ \ W/, function (s) {return S. touppercase () ;}); If (typeof this [name] === "undefined") {This [name] = function () {var ARGs = This. $ A (arguments); return this. attachevent. apply (this, [type]. concat (ARGs) }}, this)}, hasevent: function (type) {return (this. _ listeners [type] instanceof array & this. _ listeners [type]. length> 0) ;}, attachevent: funct Ion () {var ARGs = this. $ A (arguments), type = args. Shift (), callback = args. Shift (); If (! This. hasevent (type) This. _ listeners [type] = []; var listeners = This. _ listeners [type]; listeners. push ({callback: callback, argS: ARGs}) ;}, detachevent: function (type, callback) {If (this. hasevent (type) {var listeners = This. _ listeners [type], listener; If (typeof callback = "undefined") {delete this. _ listeners [type];} else {for (VAR I = 0, n = listeners. length; I <n; I ++) {If (listeners [I]. callback = Cal Lback) {listeners. splice (I, 1); Return ;}}}}, fireevent: function () {var ARGs = This. $ A (arguments), type = args. shift (); If (! This. hasevent (type) return; var listeners = This. _ listeners [type]; listeners. foreach (function (listener) {listener. callback. apply (this, listener. args. concat (ARGs)}, this );}}
Strictly speaking, this is not a class. It should be called an interface. When the target class implements it (turning the eventdispatcher member into a member of the target class) and provides an events String Array member in the prototype, we call createevents, it has event-like behavior, because there is no Dom monitoring, we need fireevent to trigger the event.
Example:
VaR person = function (name) {This. name = Name} person. prototype = {events: ["layout"]} var include = function (concrete, interface) {// use the ruby naming method, used to add an instance Member for (VAR prop in Interface) {concrete. prototype [prop] = interface [prop];} include (person, eventdispatcher); var P = new person ("situ zhengmei") p. createevents () p. onlayout (function (name) {alert (name)}); p. onlayout (function (name) {alert (name + "!! ")}); P. fireevent (" layout "," parameter ") // The" parameter "is displayed in sequence !! "
<Br/> <! Doctype HTML> <br/> <pead> <br/> <title> JavaScript Custom Event by situ zhengmei </title> </P> <p> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8 "/> </P> <p> </pead> <br/> <body> <br/> <div> situ zhengmei </div> </P> <p> <SCRIPT type = "text/JavaScript"> <br/> If (typeof array. prototype. foreach! = "Function") {<br/> array. prototype. foreach = function (FN, scope) {<br/> for (VAR I = 0, n = This. length >>> 0; I <n; I ++) {<br/> I in this & FN. call (scope, this [I], I, this) <br/>}< br/> var eventdispatcher ={< br/> $ A: function (iterable) {<br/> return array. prototype. slice. call (iterable) <br/>}, <br/> createevents: function () {<br/> This. _ listeners ={}; <br/> var names = This. events | [], Name, type; <br/> names. foreach (function (type) {<br/> name = "on" + type. replace (/_ ([A-Z])/g, function ($1, $2) {<br/> return $2. touppercase () <br/> }). replace (/^ \ W/, function (s) {<br/> return S. touppercase (); <br/>}); </P> <p> If (typeof this [name] = "undefined ") {<br/> This [name] = function () {<br/> var ARGs = This. $ A (arguments); <br/> return this. attachevent. apply (this, [type]. concat (ARGs) <br/>} <Br/>}< br/>}, this) <br/>}, <br/> hasevent: function (type) {<br/> return (this. _ listeners [type] instanceof array & this. _ listeners [type]. length> 0); <br/>}, <br/> attachevent: function () {<br/> var ARGs = This. $ A (arguments), <br/> type = args. shift (), callback = args. shift (); <br/> If (! This. hasevent (type) <br/> This. _ listeners [type] = []; <br/> var listeners = This. _ listeners [type]; <br/> listeners. push ({callback: callback, argS: ARGs}); <br/>}, <br/> detachevent: function (type, callback) {<br/> If (this. hasevent (type) {<br/> var listeners = This. _ listeners [type], listener; <br/> If (typeof callback = "undefined") {<br/> delete this. _ listeners [type]; <br/>} else {<br/> for (VAR I = 0, n = listeners. length; I <n; I ++) {<br/> If (listeners [I]. callback === callback) {<br/> listeners. splice (I, 1); <br/> return; <br/>}< br/> }, <br/> fireevent: function () {<br/> var ARGs = This. $ A (arguments), type = args. shift (); <br/> If (! This. hasevent (type) return; <br/> var listeners = This. _ listeners [type]; <br/> listeners. foreach (function (listener) {<br/> listener. callback. apply (this, listener. args. concat (ARGs) <br/>}, this); <br/>}</P> <p> var person = function (name) {<br/> This. name = Name <br/>}< br/> person. prototype = {<br/> events: ["layout"] <br/>}< br/> var include = function (concrete, interface) {// use a ruby-style name Method, used to add instance members <br/> for (VAR prop in Interface) {<br/> concrete. prototype [prop] = interface [prop]; <br/>}< br/> include (person, eventdispatcher ); <br/> var P = new person ("situ zhengmei") <br/> P. createevents () <br/> P. onlayout (function (name) {<br/> alert (name) <br/>}); <br/> P. onlayout (function (name) {<br/> alert (name + "!! ") <Br/>}); <br/> P. fireevent (" layout "," parameter ") //" parameter "is displayed in sequence !! "<Br/> </SCRIPT> </P> <p> </body> <br/> </ptml> <br/>
RunCode