When operating the dom, we often use onclick, onmouseover and other browser-specific behavior events.
Then, as the name suggests, custom events are defined by yourself and event handling functions. When appropriate, they will call which handler is needed.
Supported browser default events
Events with specific behaviors in browsers, or system events, js default events, etc., as long as you know what I mean, I will call them js default events.
I believe everyone has used the event binding, event removal and other operations of js default events, such as:
//DOM0 level event handlervar oDiv = ('oDiv'); = function(){ alert("You clicked on me"); }
Or
//DOM2 level event handlervar oDiv = ('oDiv'); // Non-ie("click",function(){ alert("You clicked on me"); },false); //ie ("onclick", function(){ alert("You clicked on me"); });
I won't do too much research. After all, let's discuss js custom events. Here is a code that I have encapsulated before to handle js default events:
// Cross-browser event handler//When calling it directly with ( , , ); call it directly//When using it, first use addEvent to add events, and then directly write other function methods in handleFun, such as getEvent;//addEventListener and attachEvent--- are both dom2 level event handlersvar domEvent = { //element:dom object, event: pending event, handleFun: processing function //Event name, does not contain "on", such as "click", "mouseover", "keydown", etc. addEvent:function(element,event,handleFun){ //addEventListener----applied to mozilla if(){ (event,handleFun,false); }//attachEvent----applied to IE else if(){ ("on"+event,handleFun); }//Other selection of dom0 level event handler else{ //===element["on"+event]; element["on"+event] = handleFun; } }, //Event name, including "on", such as "onclick", "onmouseover", "onkeydown", etc. removeEvent:function(element,event,handleFun){ //removeEventListener----applied to mozilla if () { (event,handleFun,false); }//detachEvent----applied to IE else if () { ("on"+event,handleFun); }//Other selection of dom0 level event handler else { element["on"+event] = null; } }, //Stop the bubbling of events stopPropagation:function(event){ if(){ (); }else{ = true;//IE prevents events from bubbling, true means blocking } }, //Block events default behavior preventDefault:function(event){ if(){ (); }else{ = false;//IE prevents events from bubbling, false means block } }, //Get event element //--Non-IE //--IE getElement:function(event){ return || ; }, //Get Event getEvent:function(event){ return event? event : ; }, //Get event type getType:function(event){ return ; } };
We are not as good as the topic of the following class, js custom events
2. Objects are encapsulated directly by encapsulating js custom events
Based on the above package, we can conceive it like this
var eventTarget = { addEvent: function(){ //Add event }, fireEvent: function(){ //Trigger event }, removeEvent: function(){ //Remove event } };
I believe that this is easier for everyone to understand. Then there is another question you can think of, that is, js default events, js can correspond one by one, knowing which one is that, so what about our custom events, this one-to-one mapping table can only be established by ourselves, and then I do this
var eventTarget = { //Save the map handlers:{}, addEvent: function(){ //Processing code }, fireEvent: function(){ //Trigger code }, removeEvent: function(){ //Move out the code } };
This is how I construct this mapping relationship
handlers = { "type1":[ "fun1", "fun2", // "..." ], "type2":[ "fun1", "fun2" // "..." ] //"..." }
In this way, each type can have multiple processing functions, so that we can expand it later
Next is practical code, writing specific processing code...
I believe everyone is very clear about this idea, so I will directly attach the code
//Directly handle js custom eventsvar eventTarget = { //Save event type and handle function array mapping handlers:{}, //Register event handler of a given type, //type -> Custom event type, handler -> Custom event callback function addEvent: function(type, handler){ //Discern whether there are events of this type in the event processing array if([type] == undefined){ [type] = []; } //Push the processing event into the event processing array [type].push(handler); }, // Trigger an event //event -> is a js object, the attribute contains at least the type attribute, //Because the type is necessary, secondly, you can pass some other variable parameters required by the processing function. (This is also the reason why you need to pass js objects) fireEvent: function(event){ //Judge whether the event type exists if([] instanceof Array){ var _handler = []; //In the same event type, there may be multiple processing events to find out the events that need to be processed this time for(var i = 0; i < _handler.length; i++){ //Execution trigger _handler[i](event); } } }, //Login event //type -> Custom event type, handler -> Custom event callback function removeEvent: function(type, handler){ if([type] instanceof Array){ var _handler = [type]; //In the same event type, there may be multiple processing events to find out the events that need to be processed this time for(var i = 0; i < _handler.length; i++){ //Find out the subscript of the event that needs to be processed this time if(_handler[i] == handler){ break; } } //Delete processing event _handler.splice(i, 1); } } };
This is a method to call running
("eat",function(){ (123); //123 }); ({type: "eat"});
This method has a disadvantage, and cannot delete the processing event, because we do it with a mapping table, and it is not recommended to directly store so much data in the mapping table, which is a bit too much.
Another way to extract the processing events (recommended)
function b(){ (123); } ("eat",b); ({ type: "eat" }); //123 ("eat",b); ({type: "eat"}); //null
This is also possible, passing more parameters
({ type: "eat", food: "banana" }); function b(data){ (); //banana }
Summary: The literal method has a bit of a disadvantage, which is that if you accidentally add a certain property in the handler function and assign a value of null, this will cause our eventTarget method to collapse. It seems that the prototype should be a good way and a little safer.
3. Object prototype encapsulates js custom events
Since the previous ideas have been explained clearly, I will directly attach the code here. You can study the pros and cons. Perhaps you can find a better way to solve it...
//Custom event constructorfunction EventTarget(){ //Event handler array collection = {}; } //Custom event prototype object = { //Set the prototype constructor chain constructor: EventTarget, //Register event handler of a given type, //type -> Custom event type, handler -> Custom event callback function addEvent: function(type, handler){ //Discern whether there are events of this type in the event processing array if(typeof [type] == 'undefined'){ [type] = []; } //Push the processing event into the event processing array [type].push(handler); }, // Trigger an event //event -> is a js object, the attribute contains at least the type attribute, //Because the type is necessary, secondly, you can pass some other variable parameters required by the processing function. (This is also the reason why you need to pass js objects) fireEvent: function(event){ //Simulate the event of real events if(!){ = this; } //Judge whether the event type exists if([] instanceof Array){ var handlers = []; //In the same event type, there may be multiple processing events to find out the events that need to be processed this time for(var i = 0; i < ; i++){ //Execution trigger handlers[i](event); } } }, //Login event //type -> Custom event type, handler -> Custom event callback function removeEvent: function(type, handler){ //Judge whether the event type exists if([type] instanceof Array){ var handlers = [type]; //In the same event type, multiple processing events may exist. for(var i = 0; i < ; i++){ //Find out the subscript of the event that needs to be processed this time if(handlers[i] == handler){ break; } } //Delete from the event processing array (i, 1); } } };
Calling methods
function b(){ (123); } var target = new EventTarget(); ("eat", b); ({ type: "eat" }); //123
The prototype method has the same function as the direct measurement method...
The above is all about this article, I hope it will be helpful to everyone's learning.