The birth of jquery-principle and mechanism

Source: Internet
Author: User

One, seemingly accidental things are actually inevitable to happen

When I was in college, I turned over a very shabby book in the library, talking about biological theory, the main content is to explore the birth of life is accidental or inevitable. There are a lot of things Aristotle can not understand the formula to calculate what, as well as simulating the original Earth environment has appeared organic experiments or something. In short, the view of the book is: "In the earth environment at that time, the birth of life is inevitable!" "Countless chance of accidental conditions, countless chemical reactions, such as the encounter will inevitably produce organic matter, and then more than accidental, organic matter must form an organism ...

This theory is similar to that you are a very careful person crossing the road, and you long life, except afraid of being hit by a car. Give you 1 million years of life, you must eventually be killed by the car.

If this theory is to see the advent of jquery, the conclusion should be inevitable !

Ii. demand, impetus, development, creation of things and the birth of jquery

A mature thing is obviously not out of breath, so-called "a shovel can not dig a well", I think the original author of jquery again genius, is gradually coming over, how a gradual approach, I think, is likely to be driven by demand, like knife noodles robot, is said to have been the eighth generation now!

1. The Gelelementbyid is too long.
There is a button on the page, there is a picture, I want to click the button image hidden, the following HTML:

<button id= "button" > click I </button>

So, my script might be like this:

var button = document.getElementById ("button")    , image = document.getElementById ("image") Button.onclick = function () {    Image.style.display = "None";};

What's the problem? Almost all of us are born "lazy", the document.getElementById name is long and repeated appear, as if to the company found that the card has not brought home to regain the feeling of card, I hope the easier the better. Well, I like money very much, $ this symbol I like very much, I intend to transform it and simplify my work:

var $ = function (ID) {    return document.getElementById (ID);}; $ ("button"). onclick = function () {    $ ("image"). Style.display = "None";}; 

Here $() is the simplest wrapper, just returning the native DOM object.

2. I need a simple code, like "Open sesame."
Later the page complex, click a button, there are 2 pictures to hide.

$ ("button"). onclick = function () {    $ ("Image1"). Style.display = "None";    $ ("Image2"). Style.display = "None";};

Seems to see a long repetition of things, xxx.style.display = "none" why every time the door to find the key from the bag, pointing at the plug in, but also left twist twist right twist it? Once, every day often like this how to tolerate. Imagine, if there is a sesame to open the code, "open Open", voice recognition, the door opened automatically, much worry.

Here every time to hide, xxx.style.display = "none" than to take the key to open the door is also annoying, I hope there is a quick way, for example, "Hide hidden", statement recognition, the element is automatically hidden, much worry.

is to become the following effect:

$ ("button"). onclick = function () {    $ ("Image1"). Hide ();    $ ("Image2"). Hide ();}; 

3. How to identify the "open sesame" signal
$("image1")The essence is a DOM element that $("image1").hide() extends a method on the DOM element, which is hidden by the hide call.

Oh, the expansion, immediately think of the JS prototype prototype. //ZXX: Boss, what's the cheapest dish on the street now? Boss: Prototype ah, all flooded!

HTMLElement.prototype.hide = function () {    This.style.display = "None";};

The demo address of the above code should not be seen by people ...

Although the body drilled a hole inserted into a method, after all, the browser has an effect ah, the pain is not what. However, we are in the accommodating celestial, many ie6~ie8 old stubborn, these old things do not know HTMLElement , for self- HTMLElement harm expansion of the law can not understand, and these old guys in charge of half. Alas, in the face of reality, the direct expansion of elements is not feasible.

Therefore, due to compatibility, we need to think of other extension methods.

4. All roads lead to Rome, where there is no sir
Although IE6~IE8 does not HTMLElement know the prototype extension, however, Function the prototype expands its understanding AH. No matter how it is used, it is not known for the time being, let's try a simple trial.

var F = function () {}; F.prototype.hide = function () {This    ?. Style.display = "None";}; New F (). Hide ();    //This implementation is hidden? 

This article has at least half of the content, but the full text of the most difficult is here, the understanding new F() and understanding.

The above code, new F () you can be seen as this?.style here this . You may jump up and answer: "That new F() 's the return value = DOM元素 not finished OK!" -- this.style.hide = = new F().style.hide DOM.style.hide "!

As soon as new the expression constructor Returns ( return ) a Reference object (array, object, function, and so on) will overwrite the anonymous object created by new, if it returns ( return ) an original type ( return the original type is not in fact return undefined ) , new the anonymous object that was created is returned.

The above references come from here. What do you mean? To be blunt, new F() if there is no return value ( Undefined type), or if the return value is one of 5 basic types (type, type, type, type, type Undefined Null Boolean Number String ), then new F() we can consider it as a prototype extension method this ; If the return is an array ah, object ah what, then the return value is the object itself, at this time new F()this .

To illustrate:

var F = function (ID) {    return document.getElementById (ID);}; New F ("image1") = = document.getElementById ("Image1");    //True indicates that the DOM object appears to be returned, actually a DOM object
var F = function (ID) {    return ID;}; New F ("image1") = = "Image1";    //False indicates that a string value appears to be returned, not actually a string

Back to the naïve idea above. To use prototype.hide the method this , we can't let the F function have a messy return value.

Therefore, it new F() is not advisable to return directly to the DOM, but we can use this indirect invocation. Say:

var F = function (id) {    this.element = document.getElementById (id);}; F.prototype.hide = function () {    this.element.style.display = "None";}; New F ("image"). Hide ();    //See You don't hide  

The demo address of the above code should not be seen by people ...

5. Exposing and reusing element acquisition methods
The above method, the element gets directly in the F method, but, in reality, given the compatibility implementation, the element acquisition can be quite complex, while the method is private and cannot be re-used. Therefore, the element acquisition method can be placed on the prototype for easy management and reuse. The code is as follows:

var F = function (ID) {    return This.getelementbyid (ID);}; F.prototype.getelementbyid = function (id) {    this.element = document.getElementById (ID);    this ;}; F.prototype.hide = function () {    This.element.style.display = "None";}; New F ("image"). Hide ();    //See You don't hide  

The element get method is put on prototype , by F() execution. You might be surprised that you just said, "It new F() 's not advisable to return directly to the DOM." return Everyone must eyes peeled, F.prototype.getElementById The return value is this , that is, new F() the return value is this . The image point is a new F("image") punch, and bounced back to his face.

The demo address of the above code should not be seen by people ...

6. I don't like new, I like $
new F("image")I do not like this kind of writing, I like $ , I just like $ , I want to replace.

Well, what to new hide in the $ method of the ~

var $ = function (ID) {    return new F (ID);};

So, the above image hidden direct execution code is:

$ ("image"). Hide ();

The demo address of the above code should not be seen by people ...

IE6 Browser is also supported Oh! It's a bit of a jquery look!

7. What kind of posture do you have?
Gradually to the present, are taken for id example, the actual application, we may want to use the class name Ah, tag name ah what, now, for the next continuation, it is necessary to support multiple "posture."

In the Ie8+ browser, we have the selector API, document.querySelector with document.querySelectorAll the former returning unique Node , the latter being the NodeList collection. We use the latter for the sake of great unification. So, there are:

var F = function (selector, context) {    return This.getnodelist (selector, context);}; F.prototype.getnodelist = function (selector, context) {    context = Context | | document;    This.element = context. Queryselectorall (selector);    return this;}; var $ = function (selector, context) {    return new F (selector, context);};

At this point, we can use a variety of selectors, for example, the $("body #image") this.element selected elements.

8. Ie6/ie7 swelling?
Ie6/ie7 don't know what querySelectorAll to do?

jquery uses a more powerful selector framework- Sizzle . Know just fine, heavy in the demonstration principle, therefore, the following is still using the native selector API schematic, so the demo effect needs to be viewed under the ie8+ browser.

8. Traversal is a nuisance.
this.elementAt this time the type is NodeList , therefore, this.element.style.xxx the direct approach must be an error, it seems necessary to cycle under:

F.prototype.hide = function () {    var i=0, length = this.element.length;    for (; i<length; i+=1) {        This.element[i].style.display = "None";    }    };

thus

$ ("img"). Hide ();  //Page All pictures are hidden! 

The demo address of the above code should not be seen by people ...

A simple hide method can also be dealt with, and then a show method, it is not to cycle through, not to be bored to death ~

Therefore, a way to traverse the wrapper element is urgently needed, so to name each it ~

So there are:

F.prototype. each = function (fn) {    var i=0, length = this.element.length;    for (; i<length; i+=1) {        fn.call (this.element[i], I, this.element[i]);    }    return this;}; F.prototype.hide = function () {This] each    (function () {       This.style.display = "None";    }); $ ("img"). Hide ();  //Page All pictures are hidden! 

The demo address of the above code should not be seen by people ...

9. I don't like this.element, can I get rid of it?
Now the wrapper object structure looks like this:

F.prototype = {    element: [NodeList],    each:function () {},    hide:function () {}}

elementIt looks so unsightly, can't you get rid of it? Yes, baby, NodeList It's a class array structure, and we'll assign it to the object as a numerical index. One is to remove redundant element attributes, and let the prototype object become the class array structure, which can have some special functions.

So, F.prototype.getNodeList need to change a name, say initialization init , so there are:

F.prototype. init = function (selector, context) {    var nodeList = (Context | | document). Queryselectorall (Selector );    this.length = nodelist.length;    for (var i=0; i<this.length; i+=1) {        this[i] = Nodelist[i];        }    return this;};  

At this point, each in the method, there is no annoying unsightly this.element[i] appearance, but direct this[i] .

F.prototype.each = function (fn) {    this.length;    for (; i<length; i+=1) {        fn.call (this[i]);    }    return this;}; 

We can also access the DOM elements in the wrapper directly using the index. For example: $("img")[0] is the first picture!

The demo address of the above code should not be seen by people ...

10. I am a perfectionist, I do not like the F name, can be replaced?
FThis name appears from beginning to end, I do not like to come, I want to replace $ , I just want to change the $ symbol ...

This ... $ Already used Ah, and then use the conflict. Besides, you are not Fox after, Shuawulai also useless ah ...

Well, think of some other way. Step by step, then I'll replace all of them F $.fn .

There are:

The demo address of the code should not be seen by people ...

Obviously, the operation is OK. There seems to be a lot of jquery, but, in fact, there is a difference between the jquery and the other, there is a big difference. If it is the JavaScript structure shown in the code, then the wrapper object will extend the new method, each of which needs to write another prototype. For example, to extend a attr method, you would write:

$.fn.prototype.attr = function () {    //...};

See again prototype , high-level things should be hidden, otherwise it will give people difficult to get started feeling. What should we do then? Be is not a pushover.

The mind moves a bit to know, the change is F.prototype $.fn soon good. This way, when you extend a new method, it is directly

$.fn.attr = function () {    //...};

At this point, it is very close to jquery, in terms of usage. However, there are a few F how to do it, always can not be like the following:

var $ = function (selector, context) {    return new F (selector, context);}; var F = function (selector, context) {    return This.init (selector, context);}; $.fn = F.prototype;$.fn.init = function (selector, context) {    //...    return this;}; $.fn.each = function (fn) {   //...}; $.fn.hide = function () {   //...};  

In mathematics, we have all learned to merge similar terms. Take a closer look at the code above:
$()Returns a new F() reference to the new F() object that is returned. Rub, this returns to return, the parameters are the same, we can not return at once, and then do some hands and feet, so that $.fn.init the return this will still be able to point correctly.

As a result, some adjustments are:

var $ = function (selector, context) {    return new $.fn.init (selector, context);}; var F = function () {};$.fn = F.prototype;$.fn.init = function (selector, context) {    //...    return this;}; // ...

The above code is obviously problematic, the return value is. That is, the new $.fn.init $.fn.init this $() return value is $.fn.init the prototype object, and the $.fn.init prototype is prototype now a guanggansiling ah, yo, exactly, $.fn The corresponding prototype method, in addition to the Init useless, the other hide() , each() is what we need. Therefore, we need to add this line:

$.fn.init.prototype = $.fn

$()The return value $.fn.init.prototype is then changed from $.fn one moment to the next, which is exactly how we started the extension.

So, it's done. Wait a while ...

There is still residue on F it!

Oh, that one. Fis an arbitrary function, which $ is itself a function, so it is possible to use $ the substitution directly:

var $ = function (selector, context) {    return new $.fn.init (selector, context);}; var F = function () {};   $.prototype;$.fn.init = function (selector, context) {    //...    return this;}; // ...

The demo address of the code should not be seen by people ...

In fact, if you do not have $ to have a line of the world, to the above step 9th is enough. The 10th step of jquery's handling is to show that it $ 's used so well, the code is perfect and amazing!

So far, the big core of jquery has been step by step, you can see that all of these steps are based on demand, the actual development needs to be, slowly improve, slowly expand!

11. Each extension method must be $.fn.xxxx.

$.fn.css = function () {}$.fn.attr = function () {}$.fn.data = function () {}//... )

Is there a bad feeling in front of each extension that $.fn can't be merged?

So, jquery has a way of doing it extend .

$.fn.extend ({    css:function () {},    attr:function () {},    data:function () {},    //...});

12. $ () can be not only a selector string, but also a DOM
In the init method, judge the first parameter, if it is a node, directly this[0] = this_node . over!

The following 13~? are perfect ah, add ah, compatibility treatment ah what, no value, so far!

Three, a long line of the conclusion of the team

There are other articles on the Internet that introduce the principle or mechanism of jquery, which may be understood by the parties themselves, and the reader does not understand it, and the more they say it, the more they may not understand it.

jquery is very good, like a primate man. But the birth is clearly starting from the simple. So, to understand humans, you can trace their origins. If you were God and wanted you to build a man, how would you make it, and come out in one breath? Nu wa made people also want to pinch clay figurines! Start with a single-celled organism, with natural evolution, elimination, naturally, will appear human, God he did.

The birth of jquery is also roughly the same, if you want to know about jquery, you can try the development trail of jquery in this article, and you will understand why jquery is designed, how it is designed, and so on, 1.1.

Although, the content is shallow and deep, but, in which the prototype and some of the new characteristics of the constructor, for the newcomer, there are some understanding of the threshold, I hope that my description and interpretation can let you have a ray of light, it is better.

Thank you for reading this, please point out that the article may not write the exact place, thanks again!

A little share at the end of the month in Baixing, presentation documents not even ready for a meat dregs. Therefore, the next week off the text.

The birth of jquery-principle and mechanism

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.