before formally exploring jquery's core function selector, there are still some methods, which are basically array methods used to select more specific requirements, such as getting all the ancestor Selection Elements of an element, and so on. Then there is its cache mechanism data.
// @ Author situ is beautiful | too many characters | cheng http://www.cnblogs.com/rubylouvre/ All Rights Reserved // remove the blank trim on both sides: function (text) {return (Text | ""). replace (/^ \ s + | \ s + $/g, "") ;}, // converts it to an array. A common method is makearray: function (array) {var ret = []; If (array! = NULL) {var I = array. length; // The window, strings (and functions) also have 'length' if (I = NULL | typeof array = "string" | jquery. isfunction (array) | array. setinterval) RET [0] = array; // only one element else while (I) // process the array RET [-- I] = array [I];} return ret;}, // determine whether it is in the array, similar to indexof inarray: function (ELEM, array) {for (VAR I = 0, length = array. length; I <length; I ++) // use = because On IE, window = document if (array [I] = ELEM) return I; Return-1 ;}, // Add the new element or the second array to the first array // Concat merge: function (first, second) similar to the array) {// we have to loop this way because IE & opera overwrite the length // expando of getelementsbytagname var I = 0, ELEM, Pos = first. length; // also, we need to make sure that the correct elements are being returned // (ie returns comment nodes in '*' Query) if (! Jquery. Support. getall) {While (ELEM = Second [I ++])! = NULL) if (ELEM. nodetype! = 8) first [POS ++] = ELEM;} else while (ELEM = Second [I ++])! = NULL) first [POS ++] = ELEM; return first ;}, // filter duplicate elements and use the common done object as a filter (because the key will be overwritten if the same name is replaced) unique: function (array) {var ret = [], done = {}; try {for (VAR I = 0, length = array. length; I <length; I ++) {var id = jquery. data (array [I]); If (! Done [ID]) {done [ID] = true; ret. push (array [I]) ;}}catch (e) {ret = array;} return ret ;}, // This method is really bad, this is usually related to regular expressions ...... // $. Grep ([0, 1, 2], function (n, I) {// return n> 0; //}); // [1, 2] grep: function (elems, callback, inv) {var ret = []; // go through the array, only saving the items // that pass the validator function // The method is very special, before callback! It is to prevent the callback function from returning undefined if it does not return a value by default. In this way, // is set to true. If it returns true to false, it must be negative, neutralization! = Playing, and inv does not necessarily exist. Use it! Forcibly convert to boolean for (VAR I = 0, length = elems. length; I <length; I ++) if (! Inv! =! Callback (elems [I], I) ret. push (elems [I]); return ret ;}, // map: function (elems, callback) {var ret = []; // go through the array, translating each of the items to their // new value (or values ). for (VAR I = 0, length = elems. length; I <length; I ++) {VaR value = callback (elems [I], I); If (value! = NULL) RET [ret. length] = value;} return ret. concat. apply ([], RET) ;}}); // jquery. the methods below browser have been deprecated. These are compatible with previous versions and plug-ins using VAR useragent = navigator. useragent. tolowercase (); // figure out What browser is being used jquery. browser = {version: (useragent. match (/. + (?: RV | it | Ra | IE) [\/:] ([\ D.] +)/) | [0, '0']) [1], Safari:/WebKit /. test (useragent), opera:/Opera /. test (useragent), MSIE:/MSIE /. test (useragent )&&! /Opera/. Test (useragent), Mozilla:/Mozilla/. Test (useragent )&&! /(Compatible | WebKit)/. Test (useragent)}; // parent, parents, next ...... Added to the jquery prototype, there are some filtering methods jquery. each ({parent: function (ELEM) {return ELEM. parentnode;}, parents: function (ELEM) {return jquery. dir (ELEM, "parentnode") ;}, next: function (ELEM) {return jquery. nth (ELEM, 2, "nextsibling") ;}, PREV: function (ELEM) {return jquery. nth (ELEM, 2, "previussibling") ;}, nextall: function (ELEM) {return jquery. dir (ELEM, "nextsibling") ;}, prevall: function (ELEM) {return jquery. dir (ELEM, "Previ Oussibling ");}, siblings: function (ELEM) {return jquery. sibling (ELEM. parentnode. firstchild, ELEM);}, children: function (ELEM) {return jquery. sibling (ELEM. firstchild) ;}, contents: function (ELEM) {return jquery. nodename (ELEM, "iframe ")? ELEM. contentdocument | elem.content+doc ument: jquery. makearray (ELEM. childnodes) ;}}, function (name, FN) {jquery. FN [name] = function (selector) {// method body var ret = jquery. map (this, FN); If (selector & typeof selector = "string") ret = jquery. multifilter (selector, RET); return this. pushstack (jquery. unique (RET), name, selector) ;};}); // appendto, prependto, insertbefore ...... Add it to the jquery prototype, // use the existing append, prepend ...... Method To build jquery. each ({appendto: "APPEND", prependto: "prepend", insertbefore: "before", insertafter: "after", replaceall: "replacewith"}, function (name, original) {jquery. FN [name] = function (selector) {var ret = [], insert = jquery (selector); For (VAR I = 0, L = insert. length; I <L; I ++) {var elems = (I> 0? This. clone (true): This ). get (); jquery. FN [original]. apply (jquery (insert [I]), elems); ret = ret. concat (elems);} return this. pushstack (Ret, name, selector) ;};}); // some important common static methods jquery. each ({removeattr: function (name) {jquery. ATTR (this, name, ""); If (this. nodetype = 1) This. removeattribute (name) ;}, addclass: function (classnames) {jquery. classname. add (this, classnames) ;}, re Moveclass: function (classnames) {jquery. classname. Remove (this, classnames) ;}, toggleclass: function (classnames, state) {If (typeof state! = "Boolean") State =! Jquery. classname. Has (this, classnames); jquery. classname [State? "Add": "Remove"] (This, classnames) ;}, remove: function (selector) {If (! Selector | jquery. filter (selector, [this]). length) {// prevent memory leaks jquery ("*", this ). add ([this]). each (function () {jquery. event. remove (this );//★★★★★Jquery. removedata (this) ;}); If (this. parentnode) This. parentnode. removechild (this) ;}}, empty: function () {// remove element nodes and prevent memory leaks jquery (this ). children (). remove (); // remove any remaining nodes while (this. firstchild) This. removechild (this. firstchild) ;}, function (name, FN) {jquery. FN [name] = function () {return this. each (FN, arguments) ;};}); // remove the unit value from the unit value // helper function used by the dimensions and offset Modules function num (ELEM, Prop) {return ELEM [0] & parseint (jquery. curcss (ELEM [0], prop, true), 10) | 0 ;}
next, let's look at jquery's caching mechanism. Most of jquery's performance depends on it.
// @ Author situ Zheng Mei | restlessdream | zookeeper | cheng http://www.cnblogs.com/rubylouvre/ All Rights Reserved var expando = "jquery" + now (), UUID = 0, windowdata ={}; jquery. extend ({cache :{}, data: function (ELEM, name, data) {// do not pin the pointer to window ELEM = window? Windowdata: ELEM; // set a variable VAR id = ELEM [expando] On ELEM; // compute a unique ID for the element if (! ID) // It is the ID at the same time. ELEM [expando] is assigned a value, and the value is a single digit id = ELEM [expando] = ++ UUID; // only generate the data cache if we're re // trying to access or manipulate it if (Name &&! Jquery. cache [ID]) // In jquery. the cache opens up an object for storing the ELEM-related things jquery. cache [ID] ={}; // prevent overriding the named cache with undefined values if (Data! = Undefined) // data must define jquery. cache [ID] [name] = data; // return the named cache data, or the ID for the element // determines whether the returned data is cached or the special ID return name of the element based on the existence of the second parameter? Jquery. cache [ID] [name]: ID;}, // remove the cached data removedata: function (ELEM, name) {ELEM = window? Windowdata: ELEM; var id = ELEM [expando]; // if we want to remove a specific section of the element's data if (name) {If (jquery. cache [ID]) {// remove the section of cache data Delete jquery. cache [ID] [name]; // if we 've removed all the data, remove the element's cache name = ""; for (name in jquery. cache [ID]) break; If (! Name) jquery. removedata (ELEM);} // otherwise, we want to remove all of the element's data} else {// clean up the element expando try {// ie cannot be removed directly using Delete, use removeattribute Delete ELEM [expando];} catch (e) {// IE has trouble directly removing the expando // but it's OK with using removeattribute if (ELEM. removeattribute) ELEM. removeattribute (expando);} // completely remove the data cach E // use the cache body to remove the index value of Delete jquery. cache [ID] ;}}, // number of class groups of cache elements attributes // read/write queue: function (ELEM, type, data) {If (ELEM) {type = (type | "FX") + "queue"; var q = jquery. data (ELEM, type); If (! Q | jquery. isarray (data) // Q is an array q = jquery. data (ELEM, type, jquery. makearray (data); else if (data) Q. push (data) ;}return Q ;}, // dequeue (shift) dequeue: function (ELEM, type) {var queue = jquery for the element's class array cache. queue (ELEM, type), FN = queue. shift (); If (! Type | type = "FX") fn = queue [0]; If (FN! = Undefined) fn. call (ELEM) ;}}); // enables jquery objects to obtain this cache capability. // The above static method is used for implementation. The final cache body is still jquery. cache jquery. FN. extend ({data: function (Key, value) {var parts = key. split (". "); parts [1] = parts [1]? "." + Parts [1]: ""; if (value = undefined) {var DATA = This. triggerhandler ("getdata" + parts [1] + "! ", [Parts [0]); If (Data = undefined & this. length) Data = jquery. data (this [0], key); return data === undefined & parts [1]? This. Data (parts [0]): Data;} else return this. Trigger ("setdata" + parts [1] + "! ", [Parts [0], value]). each (function () {jquery. data (this, key, value) ;}) ;}, removedata: function (key) {return this. each (function () {jquery. removedata (this, key) ;}) ;}, queue: function (type, data) {If (typeof type! = "String") {DATA = type; type = "FX";} If (Data = undefined) return jquery. queue (this [0], type); return this. each (function () {var queue = jquery. queue (this, type, data); If (type = "FX" & queue. length = 1) queue [0]. call (this) ;}) ;}, dequeue: function (type) {return this. each (function () {jquery. dequeue (this, type );});}});