Background:
In the current web development, a slightly more complex page, will involve a number of modules, especially similar to Seajs, LABJS, Requirejs and other modular tools, the front-end developer module Development has slowly become a habit, but multiple modules often have a variety of intersection, need to communicate, Need to call each other, then listener mode is an essential design mode, the front-end performance event operations. Both backbone and jquery provide a good way to handle events.
However, the real development needs of the time we often encounter the file loading sequence and event monitoring and update inconsistent requirements, such as: In a video site, there is a video processing of the JS module and user Information Processing module, now need to load the video module JS so that the first time to display the video to the user to see, But in the display of the video and the need for Video JS module will be updated in the User Information processing module to listen to the user to view the video recording module, this time because the User Information processing module is not loaded, so it will cause the event is undefined and not be executed, then we hope is even before the update, The User Information processing module is aware that it has been updated before it is initialized and executes the update. Here is the implementation of the event object that does not depend on the JS load sequence:
Basis:
(function(){ varOblistenlist = {};//Listener Event List varOB ={listen:function(listenstr,func) {if(!Oblistenlist[listenstr]) {OBLISTENLIST[LISTENSTR]= []; } Oblistenlist[listenstr].push (func); }, Update:function(listenstr,datas) {if(typeofOBLISTENLIST[LISTENSTR]! = "undefined"){ varLen =Oblistenlist[listenstr].length, I= 0; for(; i < Len; i++){ if(typeof(Oblistenlist[listenstr][i]) = = "function") {Oblistenlist[listenstr][i] (datas); } } } } }; Window. OB=OB; }()); Ob.listen ("Say",function(msg) {document.write (msg+ "<br/>"); }); Ob.update ("Say", "She Say:im your ' s!");
The basic event writing is simple, just use an object to put the function List of the monitored events in an object (Oblistenlist), and look at the traversal call at update.
Implementation of the first update, and so on when the listener will also perform the previous update:
(function(){ varOblistenlist = {},//listen to the event listObupdatelist = {},//Update Event ListObupdatelistlen = 2,//Maximum number of listener update queuesObupdatewaitflag =true ; varOB ={listen:function(listenstr,func) {if(!Oblistenlist[listenstr]) {OBLISTENLIST[LISTENSTR]= []; } Oblistenlist[listenstr].push (func); //Check to see if there have been any updates before if(typeofOBUPDATELIST[LISTENSTR]! = "undefined"){ varLstrarg =OBUPDATELIST[LISTENSTR]; for(vari = 0; i < lstrarg.length; i + +) {func (lstrarg[i]); }}, Update:function(listenstr,datas) {if(typeofOBLISTENLIST[LISTENSTR]! = "undefined"){ varLen =Oblistenlist[listenstr].length, I= 0; for(; i < Len; i++){ if(typeof(Oblistenlist[listenstr][i]) = = "function") {Oblistenlist[listenstr][i] (datas); } } } if(obupdatewaitflag) {//add data to the event update queue if(typeofOBUPDATELIST[LISTENSTR] = = "undefined") {Obupdatelist[listenstr]= []; } obupdatelist[listenstr].push (Datas); //If you exceed the maximum allowable length, do not add it to the inside to prevent overflow if(obupdatelist[listenstr].length>=Obupdatelistlen) {Obupdatewaitflag=false; } } } }; Window. OB=OB; }()); Ob.update ("Say", "She say:im your ' s!--1"); Ob.update ("Say", "She say:im your ' s!--2"); Ob.update ("Say", "She say:im your ' s!--3"); Ob.listen ("Say",function(msg) {document.write (msg+ "<br/>"); }); Ob.update ("Say", "She say:im your ' s!--4"); /*The result: * She say:im your ' s!--1 * She say:im your ' s!--2 * She say:im your ' s!--4*/
Look at the code, it is not difficult to achieve three key points:
1, in the update event when the event passed in the parameters passed into the Update event list
2, after the listener event initialization, look at the Update event list there is no corresponding events need to update the data, if any, then traverse the execution again
3, be sure to set a maximum reserved listener event Length (Obupdatelistlen) for the Update event list, because there may be some infinite updates in some complex page programs, and if you do not do so, you will inevitably cause a memory overflow.
Optimization:
(function() { if(typeofOB!== "undefined") {//preventing file duplication causes the event queue to be emptied return ; } varOblistenlist = {},//Store Listening QueueObupdatelist = {},//Storage Update QueueObupdatelistlen = 2,//Storage Update queue up to save lengthObupdatewaitflag =true;//record whether the maximum value for the storage update queue has been reached varOB =function(listenstr) {return NewOB.prototype.init (LISTENSTR); }; Ob.prototype={listenstr:"", instance:NULL, Init:function(listenstr) {if(OB.prototype.instance) {OB.prototype.instance.setListenStr (LISTENSTR); returnOB.prototype.instance; } This. SETLISTENSTR (LISTENSTR); OB.prototype.instance= This; return This; }, Setlistenstr:function(listenstr) { This. Listenstr =Listenstr; }, listen:function(func) {if( This. Listenstr) { if(!oblistenlist[ This. Listenstr]) {oblistenlist[ This. listenstr] = []; } oblistenlist[ This. Listenstr].push (func); //Check to see if there have been any updates before if(typeofobupdatelist[ This. listenstr]! = "undefined"){ varLstrarg = obupdatelist[ This. Listenstr]; for(vari = 0; i < lstrarg.length; i + +) {func.apply ( This, Lstrarg[i]); }}}, update:function(){ if(typeofoblistenlist[ This. listenstr]! = "undefined"){ varLen = oblistenlist[ This. Listenstr].length, I= 0; for(; i < Len; i++){ if(typeof(oblistenlist[ This. listenstr][i]) = = "function") {oblistenlist[ This. listenstr][i].apply ( This, arguments); } } } if(obupdatewaitflag) {if(typeofobupdatelist[ This. listenstr] = = "undefined") {obupdatelist[ This. listenstr] = []; } obupdatelist[ This. Listenstr].push (arguments); if(obupdatelist[ This. listenstr].length>=Obupdatelistlen) {Obupdatewaitflag=false; } } } }; OB.prototype.init.prototype=Ob.prototype; Window. OB=OB; //compatible with SEAJS and Requirejs if(typeofdefine = = = "function" && (Define.cmd | |define.amd)) {define ("jquery", [],function() { returnOB; }); }} ()); OB ("Say"). Update ("She Say:im your ' s!--1"); OB ("Say"). Update ("She Say:im your ' s!--2"); OB ("Say"). Update ("She Say:im your ' s!--3"); OB ("Say"). Listen (function(msg) {document.write (msg+ "<br/>"; }); O B ("Say"). Update ("He say:yes! You are mine! ");/*The result: * She Say:im your ' s!--1* She say:im your ' s!--He say:yes! you is mine!*/
Here is mainly a few points of optimization:
1, Operation optimization, using the jquery prototype model to achieve the jquery operation mode, the specific principle can refer to the "Sharp development: jquery core details and practice" this book
2, support AMD and CMD module, easy to apply directly to Seajs or Requirejs and other projects
3, prevent duplicate loading causes the list of events to be emptied
This is just my experience, the writing may not be so beautiful, but the basic function has come out, I hope that the project to help everyone, if there is any problem, can also reply.