Jquery source code series: append method implementation process

Source: Internet
Author: User
Tags throw exception

Jquery source code series: append method implementation process

No1:

// Define a local copy of jQuery
Var jQuery = function (selector, context ){
// The jQuery object is actually just the init constructor 'enabled'
Return new jQuery. fn.Init(Selector, context, rootjQuery); // call the second-step init Method
},

No2:

JQuery. fn = jQuery. prototype = {
Constructor: jQuery,
Init: Function (selector, context, rootjQuery ){
Var match, elem, ret, doc;


// Handle $ (""), $ (null), or $ (undefined)
If (! Selector ){
Return this;
}


// Handle $ (DOMElement)
If (selector. nodeType ){
This. context = this [0] = selector;
This. length = 1;
Return this;
}


// The body element only exists once, optimize finding it
If (selector = "body "&&! Context & document. body ){
This. context = document;
This [0] = document. body;
This. selector = selector;
This. length = 1;
Return this;
}



// Handle HTML strings
If (typeof selector = "string "){
// Are we dealing with HTML string or an ID?
If (selector. charAt (0) = "<" & selector. charAt (selector. length-1) ==="> "& selector. length> = 3 ){
// Assume that strings that start and end with <> are HTML and skip the regex check
Match = [null, selector, null];


} Else {
Match = quickExpr.exe c (selector );
}


// Verify a match, and that no context was specified for # id
If (match & (match [1] |! Context )){


// HANDLE: $ (html)-> $ (array)
If (match [1]) {
Context = context instanceof jQuery? Context [0]: context;
Doc = (context? Context. ownerDocument | context: document );


// If a single string is passed in and it's a single tag
// Just do a createElement and skip the rest
Ret = rsingleTag.exe c (selector );


If (ret ){
If (jQuery. isPlainObject (context )){
Selector = [document. createElement (ret [1])];
JQuery. fn. attr. call (selector, context, true );


} Else {
Selector = [doc. createElement (ret [1])];
}


} Else {
Ret = jQuery. buildFragment ([match [1], [doc]);
Selector = (ret. cacheable? JQuery. clone (ret. fragment): ret. fragment). childNodes;
}


Return jQuery. merge (this, selector );


// HANDLE: $ ("# id ")
} Else {
Elem = document. getElementById (match [2]);


// Check parentNode to catch when Blackberry 4.6 returns
// Nodes that are no longer in the document #6963
If (elem & elem. parentNode ){
// Handle the case where IE and Opera return items
// By name instead of ID
If (elem. id! = Match [2]) {
Return rootjQuery. find (selector );
}


// Otherwise, we inject the element directly into the jQuery object
This. length = 1;
This [0] = elem;
}


This. context = document;
This. selector = selector;
Return this;
}


// HANDLE: $ (expr, $ (...))
} Else if (! Context | context. jquery ){
Return (context | rootjQuery). find (selector );


// HANDLE: $ (expr, context)
// (Which is just equivalent to: $ (context). find (expr)
} Else {
Return this. constructor (context). find (selector );
}


// HANDLE: $ (function)
// Shortcut for document ready
} Else if (jQuery. isFunction (selector )){
Return rootjQuery. ready (selector );
}


If (selector. selector! = Undefined ){
This. selector = selector. selector;
This. context = selector. context;
}


Return jQuery. makeArray (selector, this );
},


// Start with an empty selector
Selector :"",


// The current version of jQuery being used
Jquery: "1.7.1 ",


// The default length of a jQuery object is 0
Length: 0,


// The number of elements contained in the matched element set
Size: function (){
Return this. length;
},


ToArray: function (){
Return slice. call (this, 0 );
},


// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
Get: function (num ){
Return num = null?


// Return a 'clean' array
This. toArray ():


// Return just the object
(Num <0? This [this. length + num]: this [num]);
},


// Take an array of elements and push it onto the stack
// (Returning the new matched element set)
PushStack: function (elems, name, selector ){
// Build a new jQuery matched element set
Var ret = this. constructor ();


If (jQuery. isArray (elems )){
Push. apply (ret, elems );


} Else {
JQuery. merge (ret, elems );
}


// Add the old object onto the stack (as a reference)
Ret. prevObject = this;


Ret. context = this. context;


If (name = "find "){
Ret. selector = this. selector + (this. selector? "": "") + Selector;
} Else if (name ){
Ret. selector = this. selector + "." + name + "(" + selector + ")";
}


// Return the newly-formed element set
Return ret;
},


// Execute a callback for every element in the matched set.
// (You can seed the arguments with an array of args, but this is
// Only used internally .)
Each: function (callback, args ){
Return jQuery. each (this, callback, args );
},


Ready: function (fn ){
// Attach the listeners
JQuery. bindReady ();


// Add the callback
ReadyList. add (fn );


Return this;
},


Eq: function (I ){
I = + I;
Return I =-1?
This. slice (I ):
This. slice (I, I + 1 );
},


First: function (){
Return this. eq (0 );
},


Last: function (){
Return this. eq (-1 );
},


Slice: function (){
Return this. pushStack (slice. apply (this, arguments ),
"Slice", slice. call (arguments). join (","));
},


Map: function (callback ){
Return this. pushStack (jQuery. map (this, function (elem, I ){
Return callback. call (elem, I, elem );
}));
},


End: function (){
Return this. prevObject | this. constructor (null );
},


// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
Push: push,
Sort: []. sort,
Splice: []. splice
};

 

No3: entry to append

 

JQuery. fn. extend ({
Text: function (text ){
If (jQuery. isFunction (text )){
Return this. each (function (I ){
Var self = jQuery (this );


Self. text (text. call (this, I, self. text ()));
});
}


If (typeof text! = "Object" & text! = Undefined ){
Return this. empty (). append (this [0] & this [0]. ownerDocument | document). createTextNode (text ));
}


Return jQuery. text (this );
},


WrapAll: function (html ){
If (jQuery. isFunction (html )){
Return this. each (function (I ){
JQuery (this). wrapAll (html. call (this, I ));
});
}


If (this [0]) {
// The elements to wrap the target around
Var wrap = jQuery (html, this [0]. ownerDocument). eq (0). clone (true );


If (this [0]. parentNode ){
Wrap. insertBefore (this [0]);
}


Wrap. map (function (){
Var elem = this;


While (elem. firstChild & elem. firstChild. nodeType = 1 ){
Elem = elem. firstChild;
}


Return elem;
}). Append (this );
}


Return this;
},


WrapInner: function (html ){
If (jQuery. isFunction (html )){
Return this. each (function (I ){
JQuery (this). wrapInner (html. call (this, I ));
});
}


Return this. each (function (){
Var self = jQuery (this ),
Contents = self. contents ();


If (contents. length ){
Contents. wrapAll (html );


} Else {
Self. append (html );
}
});
},


Wrap: function (html ){
Var isFunction = jQuery. isFunction (html );


Return this. each (function (I ){
JQuery (this). wrapAll (isFunction? Html. call (this, I): html );
});
},


Unwrap: function (){
Return this. parent (). each (function (){
If (! JQuery. nodeName (this, "body ")){
JQuery (this). replaceWith (this. childNodes );
}
}). End ();
},


Append: function (){
Return this. domManip (arguments, true, function (elem ){ If (this. nodeType = 1 ){
This. appendChild (elem );
}
});
},


Prepend: function (){
Return this. domManip (arguments, true, function (elem ){
If (this. nodeType = 1 ){
This. insertBefore (elem, this. firstChild );
}
});
},


Before: function (){
If (this [0] & this [0]. parentNode ){
Return this. domManip (arguments, false, function (elem ){
This. parentNode. insertBefore (elem, this );
});
} Else if (arguments. length ){
Var set = jQuery. clean (arguments );
Set. push. apply (set, this. toArray ());
Return this. pushStack (set, "before", arguments );
}
},


After: function (){
If (this [0] & this [0]. parentNode ){
Return this. domManip (arguments, false, function (elem ){
This. parentNode. insertBefore (elem, this. nextSibling );
});
} Else if (arguments. length ){
Var set = this. pushStack (this, "after", arguments );
Set. push. apply (set, jQuery. clean (arguments ));
Return set;
}
},


// KeepData is for internal use only -- do not document
Remove: function (selector, keepData ){
For (var I = 0, elem; (elem = this [I])! = Null; I ++ ){
If (! Selector | jQuery. filter (selector, [elem]). length ){
If (! KeepData & elem. nodeType = 1 ){
JQuery. cleanData (elem. getElementsByTagName ("*"));
JQuery. cleanData ([elem]);
}


If (elem. parentNode ){
Elem. parentNode. removeChild (elem );
}
}
}


Return this;
},


Empty: function (){
For (var I = 0, elem; (elem = this [I])! = Null; I ++ ){
// Remove element nodes and prevent memory leaks
If (elem. nodeType = 1 ){
JQuery. cleanData (elem. getElementsByTagName ("*"));
}


// Remove any remaining nodes
While (elem. firstChild ){
Elem. removeChild (elem. firstChild );
}
}


Return this;
},


Clone: function (dataAndEvents, deepDataAndEvents ){
DataAndEvents = null? False: dataAndEvents;
DeepDataAndEvents = null? DataAndEvents: deepDataAndEvents;


Return this. map (function (){
Return jQuery. clone (this, dataAndEvents, deepDataAndEvents );
});
},


Html: function (value ){
If (value = undefined ){
Return this [0] & this [0]. nodeType = 1?
This [0]. innerHTML. replace (rinlinejQuery ,""):
Null;


// See if we can take a shortcut and just use innerHTML
} Else if (typeof value = "string "&&! RnoInnerhtml. test (value )&&
(JQuery. support. leadingWhitespace |! RleadingWhitespace. test (value ))&&
! WrapMap [(rtagName.exe c (value) | ["", ""]) [1]. toLowerCase ()]) {


Value = value. replace (rxhtmlTag, "<$1> ");


Try {
For (var I = 0, l = this. length; I <l; I ++ ){
// Remove element nodes and prevent memory leaks
If (this [I]. nodeType = 1 ){
JQuery. cleanData (this [I]. getElementsByTagName ("*"));
This [I]. innerHTML = value;
}
}


// If using innerHTML throws an exception, use the fallback method
} Catch (e ){
This. empty (). append (value );
}


} Else if (jQuery. isFunction (value )){
This. each (function (I ){
Var self = jQuery (this );


Self.html (value. call (this, I, self.html ()));
});


} Else {
This. empty (). append (value );
}


Return this;
},


ReplaceWith: function (value ){
If (this [0] & this [0]. parentNode ){
// Make sure that the elements are removed from the DOM before they are inserted
// This can help fix replacing a parent with child elements
If (jQuery. isFunction (value )){
Return this. each (function (I ){
Var self = jQuery (this), old = self.html ();
Self. replaceWith (value. call (this, I, old ));
});
}


If (typeof value! = "String "){
Value = jQuery (value). detach ();
}


Return this. each (function (){
Var next = this. nextSibling,
Parent = this. parentNode;


JQuery (this). remove ();


If (next ){
JQuery (next). before (value );
} Else {
JQuery (parent). append (value );
}
});
} Else {
Return this. length?
This. pushStack (jQuery. isFunction (value )? Value (): value), "replaceWith", value ):
This;
}
},


Detach: function (selector ){
Return this. remove (selector, true );
},


DomManip: Function (args, table, callback ){
Var results, first, fragment, parent,
Value = args [0],
Scripts = [];


// We can't cloneNode fragments that contain checked, in WebKit
If (! JQuery. support. checkClone & arguments. length = 3 & typeof value = "string" & rchecked. test (value )){
Return this. each (function (){
JQuery (this). domManip (args, table, callback, true );
});
}


If (jQuery. isFunction (value )){
Return this. each (function (I ){
Var self = jQuery (this );
Args [0] = value. call (this, I, table? Self.html (): undefined );
Self. DomManip(Args, table, callback );
});
}


If (this [0]) {
Parent = value & value. parentNode;


// If we're in a fragment, just use that instead of building a new one
If (jQuery. support. parentNode & parent. nodeType ===11 & parent. childNodes. length === this. length ){
Results = {fragment: parent };


} Else {
Results = jQuery. BuildFragment(Args, this, scripts); // construct a new instance
}


Fragment = results. fragment;


If (fragment. childNodes. length = 1 ){
First = fragment. firstChild;
} Else {
First = fragment. firstChild;
}


If (first ){
Table = table & jQuery. nodeName (first, "tr ");


For (var I = 0, l = this. length, lastIndex = l-1; I <l; I ++ ){
Callback. call (
Table?
Root (this [I], first ):
This [I],
// Make sure that we do not leak memory by inadvertently discarding
// The original fragment (which might have attached data) instead
// Using it; in addition, use the original fragment object for the last
// Item instead of first because it can end up being emptied incorrectly
// In certain situations (Bug #8070 ).
// Fragments from the fragment cache must always be cloned and never used
// In place.
Results. cacheable | (l> 1 & I <lastIndex )?
JQuery. clone (fragment, true, true ):
Fragment
);
}
}


If (scripts. length ){
JQuery. each (scripts, evalScript );
}
}


Return this;
}
});

 

 

//BuildFragment Method

JQuery. buildFragment = function (args, nodes, scripts ){
Var fragment, cacheable, cacheresults, doc,
First = args [0];


// Nodes may contain either an explicit document object,
// A jQuery collection or context object.
// If nodes [0] contains a valid object to assign to doc
If (nodes & nodes [0]) {
Doc = nodes [0]. ownerDocument | nodes [0];
}


// Ensure that an attr object doesn' t incorrectly stand in as a document object
// Chrome and Firefox seem to allow this to occur and will throw exception
// Fixes #8950.
If (! Doc. createDocumentFragment ){
Doc = document;
}


// Only cache "small" (1/2 KB) HTML strings that are associated with the main document
// Cloning options loses the selected state, so don't cache them
// IE 6 doesn' t like it when you putOrElements in a fragment
// Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache
// Lastly, IE6, 7,8 will not correctly reuse cached fragments that were created from unknown elems #10501
If (args. length = 1 & typeof first = "string" & first. length <512 & doc = document &&
First. charAt (0) ===" <"&&! Rnocache. test (first )&&
(JQuery. support. checkClone |! Rchecked. test (first ))&&
(JQuery.support.html 5 Clone |! Rnoshimcache. test (first ))){


Cacheable = true;


Cacheresults = jQuery. fragments [first];
If (cacheresults & cacheresults! = 1 ){
Fragment = cacheresults;
}
}


If (! Fragment ){
Fragment = doc. createDocumentFragment ();
JQuery. clean (args, doc, fragment, scripts );
}


If (cacheable ){
JQuery. fragments [first] = cacheresults? Fragment: 1;
}


Return {fragment: fragment, cacheable: cacheable };
};

 

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.