How to bind javascript events _ basic knowledge

Source: Internet
Author: User
This article mainly introduces the learning points of javascript event binding, including the following four aspects. traditional event binding problems 2. w3C event processing function, 3. IE event processing function, 4. other additions to event objects. For more information about event binding, see the following two types of event binding: traditional event binding (Inline model, script model ), one is modern event binding (DOM2-level model ). Modern event binding provides greater and more convenient functions in traditional binding.

A traditional event binding Problem

Inline models in traditional event binding are rarely discussed. Let's take a look at the script model. The script model assigns a function to an event processing function. Traditional bindings such:

window.onload=function(){ var box=document.getElementById('box'); box.onclick = function(){  alert('Lee'); };};

Problem 1: one event processing function triggers two events

If a page has two or more JavaScript codes, and the first JavaScript code is developed by the first program, the second JavaScript code is developed by the second programmer. The first window. onload is overwritten, as shown in figure

window.onload=function(){ alert('Lee');};window.onload=function(){ alert('Mr.lee');} 

Only Mr. lee is printed.

There is actually a way to solve this problem. Let's look at the two forms below.
A:

Alert (window. onload); // The window is not registered at the beginning. onload, Which is nullwindow. onload = function () {alert ('Lee ') ;}; alert (window. onload); // If window already exists. onload: prints the functionwindow function. onload = function () {alert ('Mr. lee ');}

B:

Alert (typeof window. onload); // No window at the beginning. the old version of Firefox displays undefined. The new version displays object and window. onload = function () {alert ('Lee ') ;}; alert (typeof window. onload); // If window already exists. onload, all browsers will display functionwindow. onload = function () {alert ('Mr. lee ');}

So there is a solution.

Window. onload = function () {alert ('lil') ;}; if (typeof window. onload = 'function') {var saved = null; // save the last event object saved = window. onload;} // saved is the window. onload, saved () is equivalent to window. onload (), but window. onload () cannot be executed // so saved () is equivalent to window. onload = function () {} window. onload = function () {if (saved) {saved (); // execute the previous event window. onload = function () {}} alert ('Mr. lee '); // execute this event}

Question 2: Event switcher
Switch A p with the id of box to switch the background red and blue directly:

Window. onload = function () {var box = document. getElementById ('box'); box. className = "red"; box. onclick = function () {alert ('lil'); // only blue is executed once. call (this); // call a function through an anonymous function. this indicates the window, so you can pass it through call.} function blue () {this. className = "blue"; this. onclick = red;} function red () {this. className = "red"; this. onclick = blue ;}

Although the above Code implements the switchover function, the dialog box is executed only once.

// Add the event function // obj equivalent to window // type equivalent to onload // fn equivalent to function () {} function addEvent (obj, type, fn) {// used to save the previous event var saved = null; if (typeof obj ['on' + type] = 'function ') {saved = obj ['on' + type]; // Save the previous event} obj ['on' + type] = function () {if (saved) {saved ();} fn. call (this) ;}} addEvent (window, 'load', function () {var box = document. getElementById ("box"); // addEvent (box, 'click', function () {// this is achieved, and is executed every time, not overwritten // alert ('ss'); //}); addEvent (box, 'click', blue) ;}); function red () {this. className = "red"; addEvent (box, 'click', blue);} function blue () {this. className = "blue"; addEvent (box, 'click', red);} // when switching continuously, the browser suddenly gets stuck and reports an error: too much recursion, too many recursion // because too many stored events are accumulated // the solution is to use up the events and immediately remove them.

According to the above Code, there is an error in the comment. The solution is as follows:

// Add the event function // obj equivalent to window // type equivalent to onload // fn equivalent to function () {} function addEvent (obj, type, fn) {// used to save the previous event var saved = null; if (typeof obj ['on' + type] = 'function ') {saved = obj ['on' + type]; // Save the previous event} obj ['on' + type] = function () {if (saved) {saved ();} fn. call (this) ;}// when switching continuously, the browser suddenly gets stuck and reports an error: too much recursion, too many recursion // because too many stored events are accumulated // solution, the event is used up, and the event function removeEvent (obj, type) is removed immediately) {if (obj ['on' + type]) {obj ['on' + type] = null ;}} addEvent (window, 'load', function () {var box = document. getElementById ("box"); // addEvent (box, 'click', function () {// this is achieved, and is executed every time, not overwritten // alert ('ss'); //}); addEvent (box, 'click', blue) ;}); function red () {this. className = "red"; removeEvent (this, 'click'); addEvent (box, 'click', blue);} function blue () {this. className = "blue"; removeEvent (this, 'click'); addEvent (box, 'click', red );}

2. W3C event processing functions
AddEventListener () and removeEventListener ()
W3C event processing functions: addEventListener () and removeEventListener ().

// Two add events and delete events that come with W3C
1. Cover the problem and solve it

window.addEventListener('load',function(){ alert('Lee');},false);window.addEventListener('load',function(){ alert('Mr.Lee');},false);window.addEventListener('load',function(){ alert('Mrs.Lee');},false);

2. Solve the Problem of shielding the same function

window.addEventListener('load',init,false);window.addEventListener('load',init,false);window.addEventListener('load',init,false);function init(){ alert('Lee');}

3. Can this be passed?
Example 1:

window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',function(){  alert(this); },false);},false);

Example 2:

window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',blue,false);},false);function red(){ this.className="red"; this.removeEventListener('click',red,false); this.addEventListener('click',blue,false);}function blue(){ this.className="blue"; this.removeEventListener('click',blue,false); this.addEventListener('click',red,false);}

4. add an additional method, will it be overwritten, or it can only be executed once.

window.addEventListener('load',function(){ var box=document.getElementById('box'); box.addEventListener('click',function(){  alert('Lee'); },false); box.addEventListener('click',blue,false);},false);

To sum up, W3C perfectly solves these problems and is very easy to use. However, IE8 and earlier browsers do not support this, but use their own events, of course, IE9 fully supports W3C's two event processing functions.

W3C can set the bubble and capture modes.

Supports W3C standard browsers to use the addEventListener (event, fn, useCapture) method when adding events. In the base, the 3rd parameter useCapture is a Boolean value to set the event to be executed during event capture, or when the event is bubbling. The W3C-compatible browser (IE) uses the attachEvent () method. This method has no relevant settings. However, the event model of IE is executed during event bubbling by default, that is, it is executed when useCapture is equal to false. Therefore, it is safer to set useCapture to false when processing events, and it is also compatible with browsers.

Event capture phase: searches for events from the top-level tag until the event target is captured ).
Event bubble stage: events start from the event target and bubble up until the top-level tag of the page.
Event propagation can be prevented:
In W3c, use the stopPropagation () method
Set cancelBubble = true in IE;

Iii. IE event processing functions

AttachEvent () and detachEvent ()
IE implements two methods similar to that in DOM: attachEvent () and detachEvent (). The two methods use the same parameters: event name and function.

When using these two groups of functions, let's talk about the difference: 1. IE does not support capture, only supports bubbling; 2. duplicate functions cannot be blocked when adding events to IE; 3. in IE, this points to a window rather than a DOM object. 4. In traditional events, IE cannot accept event objects, but attchEvent can be used, but there are some differences.

1. The coverage problem is solved, but it is different. The result is Mrs. Lee, Mr. Lee, and finally Lee.

window.attachEvent('onload',function(){ alert('Lee');});window.attachEvent('onload',function(){ alert('Mr.Lee');});window.attachEvent('onload',function(){ alert('Mrs.Lee');});

2. The problem of shielding the same function has not been solved.

window.attachEvent('onload',init);window.attachEvent('onload',init);function init(){ alert('Lee');}

3. Can this be passed? No, this indicates window. The call method is required.

window.attachEvent('onload',function(){ var box=document.getElementById('box'); box.attachEvent('onclick',function(){  //alert(this===box);  alert(this===window); //true });});

The following method is to use window. event. srcElement. The Code is as follows:

window.attachEvent('onload',function(){ var box=document.getElementById('box'); box.attachEvent('onclick',blue);});function red(){ var that=window.event.srcElement; that.className="red"; that.detachEvent('onclick',red); that.attachEvent('onclick',blue);}function blue(){ var that=window.event.srcElement; that.className="blue"; that.detachEvent('onclick',blue); that.attachEvent('onclick',red);}

4. add an additional method and check whether the method will be overwritten or executed only once.

In traditional binding, IE cannot accept event objects by passing parameters like W3C, but it is acceptable to use attachEvent.

Window. attachEvent ('onload', function () {var box = document. getElementById ('box'); box. onclick = function (evt) {// the traditional method IE cannot obtain evt alert (evt) through parameters; // undefined} box. attachEvent ('onclick', function (evt) {alert (evt); // object alert (evt. type); // click alert (evt. srcElement. tagName); // DIV alert (window. event. srcElement. tagName); // DIV });});

Cross-browser compatibility

Add events across browsers

function addEvent(obj,type,fn){ if(obj.addEventListener){  obj.addEventListener(type,fn,false); }else if(obj.attachEvent){  obj.attachEvent('on'+type,fn); }}

Cross-browser removal event

function removeEvent(obj,type,fn){ if(obj.removeEventListener){  obj.removeEventListener(type,fn,false); }else if(obj.detachEvent){  obj.detachEvent('on'+type,fn); }}

Cross-browser retrieval of target objects

function getTarget(evt){ if(evt.target){  return evt.target; }else if(window.event.srcElement){  return window.event.srcElement; }}

Call method:

addEvent(window,'load',function(){ var box=document.getElementById('box'); addEvent(box,'click',blue);});function red(evt){ var that=getTarget(evt); that.className="red"; removeEvent(that,'click',red); addEvent(that,'click',blue);}function blue(evt){ var that=getTarget(evt); that.className="blue"; removeEvent(that,'click',blue); addEvent(that,'click',red);}

4. Additional event objects

RelatedTarget event

A relatedTarget event in w3c.
For example:

AddEvent (window, 'load', function () {var box = document. getElementById ('box'); addEvent (box, 'mouseover', function (evt) {alert (evt. relatedTarget); // get the closest DOM object to the box}); addEvent (box, 'mouseout', function (evt) {alert (evt. relatedTarget); // remove the nearest DOM object from the box });});

IE provides the fromElement and toElement attributes used for migration and removal, respectively, corresponding to mouseover and mouseout.

AddEvent (window, 'load', function () {var box = document. getElementById ('box'); addEvent (box, 'mouseover', function () {alert (window. event. fromElement. tagName); // get the DOM object closest to the box}); addEvent (box, 'mouseout', function () {alert (window. event. toElement. tagName); // remove the nearest DOM object from the box });});

PS: fromElement and toElement have no meaning if they correspond to the opposite mouse event.

The remaining steps are cross-browser compatibility:

function getTarget(evt){ var e=evt || window.event; if(e.srcElment){ //IE  if(e.type=='mouseover'){   return e.fromElement.tagName;  }else if(e.type="mouseout"){   return e.toElement.tagName;  } }else if(e.relatedTarget){ //w3c  return e.relatedTarget; }}

Shield jump operations

The default action of canceling an event is to return false.

link.onclick=function(){ alert('Lee'); return false;}

PS: Although return false; can implement this function, there is a vulnerability.
First, it must be written to the end. As a result, after the winning code is executed, return false may not be executed;
Second, if return false is written to the beginning, the subsequent custom operations will become invalid.
So the best way is to stop the default behavior at the beginning, and the subsequent code can be executed.

Link. onclick = function (evt) {evt. preventDefault; // w3c, blocking default behavior alert ('lil');} link. onclick = function (evt) {window. event. returnValue = false; // IE, blocks the default behavior alert ('lil ');}

Cross-browser compatibility:

function preDef(evt){ var e=evt || window.event; if(e.preventDefault){  e.preventDefault(); }else{  e.returnValue=false; }}

Right-click contextmenu
Compatibility:

function preDef(evt){ var e=evt || window.event; if(e.preventDefault){  e.preventDefault(); }else{  e.returnValue=false; }}addEvent(window,"load",function(){ var body=document.getElementsByTagName('body')[0]; addEvent(body,'contextmenu',function(evt){  preDef(evt); })});

PS: contextmenu events are frequently used, which directly leads to stable browser compatibility.

Events Before uninstallation: beforeunload
This event can help you give a corresponding prompt when you leave this page, "exit" or "return" operation.

addEvent(window,'beforeonload',function(){ preDef(evt);});

Mouse wheel (mousewheel) and DOMMouseScroll
Used to obtain the distance between the cursor and the scroll wheel

AddEvent (document, 'mousewheel ', function (evt) {// non-Firefox alert (getWD (evt) ;}); addEvent (document, 'dommousescroll', function (evt) {// Firefox alert (getWD (evt) ;}); function getWD (evt) {var e = evt | window. event; if (e. wheelDelta) {return e. wheelDelta;} else if (e. detail) {// Firefox return-evt. detail * 30 ;}}

PS: through browser detection, it can be determined that Firefox only executes DOMMouseScroll.

DOMContentLoaded event and readystatechange event

DOMContentLoaded event and readystatechange event are related to DOM loading events.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.