JQuery3.1.1 Source code Interpretation (12) "Event-extend"

Source: Internet
Author: User
Tags bind event listener extend split wrapper

The previous chapter, which is probably an overview, describes the purpose and use of event binding, knowing what kind of process it is inside, from which function to which function. Whether jquery's source code is simple or complex, it is certain that jquery is committed to solving browser compatibility issues and ultimately serving users. Some legacy issues

When we first introduced Bind, delegate and their UN methods, we were reminded to forget to mention some of the content that we often use. such as $ (' body '). click,$ (' body '). MouseLeave, etc., they are directly defined in the prototype function, do not know how, they are ignored.

Jquery.each (("Blur Focus Focusin focusout resize Scroll click DblClick" +
  "MouseDown mouseup mousemove mouseover mo Useout mouseenter MouseLeave "+
  " Change select Submit KeyDown keypress keyup ContextMenu "). Split (" "),
  Functio  N (i, name) {

  //Handle Event binding
  jquery.fn[Name] = function (data, FN) {
    return arguments.length > 0?
      This.on (name, NULL, data, FN):
      This.trigger (name);
  };
});

This structure is also very ingenious, these methods composed of a string through the split ("") into an array, and then through each method, the prototype corresponding to each name, define the function, here you can see, is still on, and Targger:

JQuery.fn.extend ({
  trigger:function (type, data) {
    return This.each (function () {//////
      is still a method on the event object
      JQuery.event.trigger (type, data, this);}
    )
  }
} )

There is also a missing one method, which means that the bound event is executed only once with the type. One ():

JQuery.fn.extend ({
  one:function (types, selector, data, FN) {
    //global on function
    return on (this, types, selector, Data, FN, 1);
  },}
);
DOM Event Knowledge points

found that with the continuous deepening of the source of the event, I myself appear more and more problems, such as not to see the addeventlistener I am familiar with, there are some very confused events, so I decided to first read the DOM in JS event it. Early DOM Events

In the DOM object of HTML, there are some familiar things that start with on, such as OnClick, onmouseout, and so on, these are the early DOM events, the simplest use of which is to support the writing of functions directly on the object by name:

document.getElementsByTagName (' body ') [0].onclick = function () {
  console.log (' click! ');
}
document.getElementsByTagName (' body ') [0].onmouseout = function () {
  console.log (' Mouse out! ');
}

The onclick function passes an event parameter by default, indicating the state at the time the event was triggered, including the trigger object, coordinates, and so on.

There is a very big drawback to this approach, which is that events of the same name will be overwritten before a click function overwrites the previous click function:

var BODY = document.getelementsbytagname (' body ') [0];
Body.onclick = function () {
  console.log (' Click1 ');
}
Body.onclick = function () {
  console.log (' Click2 ');
}
"Click2"
body.onclick = null;
No effect
DOM 2.0

With the development of DOM, has come to 2.0 times, that is, I am familiar with AddEventListener and attachevent (IE), JS event bubbling and capture. This time compared to before, the change is really too big, MDN AddEventListener ().

Change is changing, but browser compatibility is a big problem, such as the following can be implemented does not support the AddEventListener browser:

(function () {//does not support Preventdefault if (!
    Event.prototype.preventDefault) {event.prototype.preventdefault=function () {this.returnvalue=false;
  }; }//Does not support stoppropagation if (!
    Event.prototype.stopPropagation) {event.prototype.stoppropagation=function () {this.cancelbubble=true;
  }; }//Does not support AddEventListener time if (!

    Element.prototype.addEventListener) {var eventlisteners=[];
      var addeventlistener=function (Type,listener/*, usecapture ('ll be ignored) */) {var self=this;
        var wrapper=function (e) {e.target=e.srcelement;
        e.currenttarget=self;
        if (typeof listener.handleevent! = ' undefined ') {listener.handleevent (e);
        } else {Listener.call (self,e);
      }
      };
            if (type== "domcontentloaded") {var wrapper2=function (e) {if (document.readystate== "complete") {
          Wrapper (e);
        }
        }; Document.attachevent ("OnreadystatEchange ", wrapper2);

        Eventlisteners.push ({object:this,type:type,listener:listener,wrapper:wrapper2});
          if (document.readystate== "complete") {var e=new Event ();
          E.srcelement=window;
        Wrapper2 (e);
        }} else {this.attachevent ("on" +type,wrapper);
      Eventlisteners.push ({object:this,type:type,listener:listener,wrapper:wrapper});
    }
    };
      var removeeventlistener=function (Type,listener/*, usecapture ('ll be ignored) */) {var counter=0;
        while (counter<eventlisteners.length) {var eventlistener=eventlisteners[counter];
          if (eventlistener.object==this && eventlistener.type==type && eventlistener.listener==listener) {
          if (type== "domcontentloaded") {this.detachevent ("onreadystatechange", eventlistener.wrapper);
          } else {this.detachevent ("on" +type,eventlistener.wrapper); } eventlisteners.splice (counter, 1);
          Break
      } ++counter;
    }
    };
    Element.prototype.addeventlistener=addeventlistener;
    Element.prototype.removeeventlistener=removeeventlistener;
      if (htmldocument) {htmldocument.prototype.addeventlistener=addeventlistener;
    Htmldocument.prototype.removeeventlistener=removeeventlistener;
      } if (Window) {window.prototype.addeventlistener=addeventlistener;
    Window.prototype.removeeventlistener=removeeventlistener; }
  }
})();

Although browsers that do not support AddEventListener can implement this functionality, they are implemented by the Attachevent function in essence, and it is relatively urgent to understand how the early events of the DOM are built. Addevent Library

This blog post in Addevent was published in October 2005, so the Addevent method described in this blog is typical, even if the event method in JQuery is taken for this reason, it is worth mentioning:

function addevent (element, type, handler) {//Add an identity GUID to each of the functions to be bound if (!handler.$ $guid) handler.$ $guid = Addevent.gu
  id++;
  Creates an event object on the bound object event if (!element.events) element.events = {};
  A type corresponds to a handlers object, such as click to handle multiple functions at the same time var handlers = Element.events[type];
    if (!handlers) {handlers = Element.events[type] = {};
    If the onclick already exists a function, take over if (element["on" + type]) {handlers[0] = element["on" + type];
  }}//Prevent duplicate bindings, each corresponding to a GUID handlers[handler.$ $guid] = handler;
Replace the onclick function with Handleevent element["on" + type] = Handleevent;
};

Initial GUID addevent.guid = 1; function removeevent (element, type, handler) {//delete the event handler from the hash table if (element.events &amp
  ;& Element.events[type]) {delete element.events[type][handler.$ $guid];

}//Feel the back is not to add a judgment, when Element.events[type] is empty, together deleted}; function Handleevent (event) {//Grab the event object (IE uses a global event object) event = Event | | window. event;
  Here the this points to element var handlers = This.events[event.type]; Execute every event handler for (Var i in handlers) {//Here is a small trick, why not execute directly, but first bind to this after execution//is for the function to execute when the internal th
    is points to element this.$ $handleEvent = handlers[i];
  this.$ $handleEvent (event); }
};

If you can see the above addevent Library of these code to understand, then look at JQuery's events source code is more clear.

There is also a problem, the so-called event listener, is to bind the event to the parent element or document, the child element to respond to, how to implement.

Parameters to be passed in by event E:

var BODY = document.getelementsbytagname (' body ') [0];
Body.onclick = function (e) {
  console.log (e.target.classname);
}

This E.target object is the click of the child element, whether it is capturing or bubbling, or seemingly can be simulated. Next, you may have to really get to the point. Summary

Feel event delegate code is quite complicated, I also ate a lot of days, there is a little clue, which there are a lot of vague knowledge points, just feel that the existence is a good, I do not understand, but does not mean it is not good. Reference

JQuery 2.0.3 Source Analysis Event Architecture

Addevent Library

MDN Eventtarget.addeventlistener ()

Native JavaScript Event details

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.