There are many useful auxiliary methods in sizzle. Let's continue reading them one by one. It involves many bug fixes and some very rare APIs.
// @ Author situ Zheng Mei | zookeeper | cheng http://www.cnblogs.com/rubylouvre/ All Rights Reserved var sortorder; // compare the order of the two elements on the page, return a positive number, 0, negative number // If the comparedocumentposition method is supported, the newest standard browser supports it // I have a detailed introduction in the article JavaScript contains method // http://www.cnblogs.com/rubylouvre/archive/2009/10/14/1583523.html if (document.doc umentelement. comparedocumentposition) {sortorder = function (a, B) {// node A before Node B, VAR ret =. comparedocumentpo Sition (B) & 4? -1: A = B? 0: 1; if (ret = 0) {hasduplicate = true;} return ret ;}; // for IE // sourceindex refers to the position of the element in nodelist} else if ("sourceindex" in document.doc umentelement) {sortorder = function (a, B) {var ret =. sourceindex-B. sourceindex; If (ret = 0) {hasduplicate = true;} return ret ;}; // used for the legacy standard browser} else if (document. createRange) {sortorder = function (a, B) {var arange =. ownerdocument. createRange (), brange = B. ownerdocument. createRange (); arange. selectnode (a); arange. collapse (true); brange. selectnode (B); brange. collapse (true); // compare the positions of two selections // https://developer.mozilla.org/en/DOM/range.compareBoundaryPoints var ret = arange. compareboundarypoints (range. start_to_end, brange); If (ret = 0) {hasduplicate = true;} return ret ;};}
You can also use uniquenumber to compare the element positions in IE. All elements are allocated numbers from top to bottom.
Next, we will adjust getelementbyid, getelementsbytagname, getelementsbyclassname, and queryselectorall.
// If getelementbyid (XXX) has a bug in IE, it will find the first element whose name or ID is equal to XXX, // especially in the Form element, they usually have the name attribute (function () {// We're re going to inject a fake input element with a specified namevar form = document. createelement ("form"), id = "script" + (new date ). gettime (); form. innerhtml = "<input name = '" + ID + "'/>"; // inject it into the root element, check its status, and remove it quicklyvar root = document.doc umentelement; root. I Nsertbefore (Form, root. firstchild); // the workaround has to do additional checks after a getelementbyid // which slows things down for other browsers (hence the branching) if (!! Document. getelementbyid (ID) {// reload expr. Find. idexpr. Find. ID = function (match, context, isxml) {If (typeof context. getelementbyid! = "Undefined "&&! Isxml) {var M = context. getelementbyid (Match [1]); // determine whether the element explicitly assigns a return m value to the ID? M. ID = match [1] | typeof M. getattributenode! = "Undefined" & M. getattributenode ("ID"). nodevalue = match [1]? [M]: undefined: [] ;}}; expr. filter. id = function (ELEM, match) {// determine whether this element explicitly assigns a value for ID var node = typeof ELEM. getattributenode! = "Undefined" & ELEM. getattributenode ("ID"); Return ELEM. nodetype === 1 & node. nodevalue = match;} root. removechild (form) ;}) (); (function () {// check to see if the browser returns only elements // when doing getelementsbytagname ("*") // create a fake elementvar DIV = document. createelement ("Div"); Div. appendchild (document. createcomment (""); // make sure no comments are foundif (div. get Elementsbytagname ("*"). length> 0) {// reload expr. find. tagexpr. find. tag = function (match, context) {var Results = context. getelementsbytagname (Match [1]); // filter out possible comments // returns the descendant of all its element nodes to form a pure array if (Match [1] = "*") {var TMP = []; for (VAR I = 0; Results [I]; I ++) {If (results [I]. nodetype = 1) {TMP. push (results [I]) ;}} Results = TMP;} return results ;};}// check to see if an attribute re Turns normalized href attributes // process the href attribute. If the second parameter is set, ie returns the absolute path Div. innerhtml = "<a href = '#'> </a>"; if (div. firstchild & typeof Div. firstchild. getattribute! = "Undefined" & Div. firstchild. getattribute ("href ")! = "#") {Expr. attrhandle. href = function (ELEM) {return ELEM. getattribute ("href", 2) ;}}}) (); If (document. queryselectorall) (function () {// create an element fragment <div> <P class = 'test'> </P> </div> // use queryselectorall to check whether the P element var oldsizzle = is found correctly. sizzle, DIV = document. createelement ("Div"); Div. innerhtml = "<P class = 'test'> </P>"; // Safari can't handle uppercase or Unicode characters when // In quirks mode. if (div. quer Yselectorall & Div. queryselectorall (". test "). length = 0) {return;} // If yes, use queryselectorall to reload the entire sizzle engine, with the highest efficiency !!! Sizzle = function (query, context, extra, seed) {context = context | document; // only use queryselectorall on non-XML statements // (ID selectors don't work in non-HTML statements) if (! Seed & context. nodetype ===9 &&! Isxml (context) {try {return makearray (context. queryselectorall (query), extra);} catch (e) {}} return oldsizzle (query, context, extra, seed);}; sizzle. find = oldsizzle. find; sizzle. filter = oldsizzle. filter; sizzle. selectors = oldsizzle. selectors; sizzle. matches = oldsizzle. matches ;}) (); If (document. getelementsbyclassname & document.doc umentelement. getelementsbyclassname) (function () {// create an element fragment <Div> <Div class = 'test E'> </div> <Div class = 'test'> </div> // use getelementsbyclassname to check whether the two objects are correctly found. div element var DIV = document. createelement ("Div"); Div. innerhtml = "<Div class = 'test E'> </div> <Div class = 'test'> </div> "; // opera can't find a second classname (in 9.6) if (div. getelementsbyclassname ("e "). length = 0) return; // safari caches class attributes, doesn't catch changes (in 3.2) Div. lastchild. classnm E = "e"; if (div. getelementsbyclassname ("e "). length = 1) return; // re-adjust the logic expr related to the class. order. splice (1, 0, "class"); expr. find. class = function (match, context, isxml) {If (typeof context. getelementsbyclassname! = "Undefined "&&! Isxml) {return context. getelementsbyclassname (Match [1]) ;};}) ();
// This is used for the descendant selector and elder brother selector to obtain all elements in a certain range and prevent repeated acquisition of function dirnodecheck (Dir, cur, donename, checkset, nodecheck, isxml) {var sibdir = dir = "previussibling "&&! Isxml; // checkset is a set of elements, and donename is a number for (VAR I = 0, L = checkset. length; I <L; I ++) {var ELEM = checkset [I]; If (ELEM) {If (sibdir & ELEM. nodetype = 1) {ELEM. sizcache = donename; // set a flag. ELEM is not repeated if it is equal to the value. sizset = I;} ELEM = ELEM [dir]; var match = false; while (ELEM) {If (ELEM. sizcache === donename) {// compare whether match = checkset [ELEM. sizset]; break;} If (ELEM. nodetype = 1 &&! Isxml) {ELEM. sizcache = donename; ELEM. sizset = I;} If (ELEM. nodename = cur) {match = ELEM; break;} ELEM = ELEM [dir];} checkset [I] = match ;}}// similar to the above functions, I wonder if it is out of compatibility with previous versions ...... Function dircheck (Dir, cur, donename, checkset, nodecheck, isxml) {var sibdir = dir = "previussibling "&&! Isxml; For (VAR I = 0, L = checkset. length; I <L; I ++) {var ELEM = checkset [I]; If (ELEM) {If (sibdir & ELEM. nodetype = 1) {ELEM. sizcache = donename; ELEM. sizset = I;} ELEM = ELEM [dir]; var match = false; while (ELEM) {If (ELEM. sizcache === donename) {match = checkset [ELEM. sizset]; break;} If (ELEM. nodetype = 1) {If (! Isxml) {ELEM. sizcache = donename; ELEM. sizset = I;} If (typeof cur! = "String") {If (ELEM = cur) {match = true; break;} else if (sizzle. filter (cur, [ELEM]). length> 0) {match = ELEM; break;} ELEM = ELEM [dir];} checkset [I] = match ;}}}
// Determine if one element contains another element // http://www.cnblogs.com/rubylouvre/archive/2009/10/14/1583523.html var contains = Document. comparedocumentposition? Function (a, B) {return a. comparedocumentposition (B) & 16;}: function (a, B) {return! = B & (A. contains? A. contains (B): True) ;}; // judge whether it is XML var isxml = function (ELEM) {return ELEM. nodetype = 9 & amp; elem.doc umentelement. nodename! = "Html" | !! ELEM. ownerdocument & isxml (ELEM. ownerdocument) ;}; // mainly processes the subelement filter var posprocess = function (selector, context) {var tmpset = [], later = "", match, root = context. nodetype? [Context]: context; // position selectors must be done after the filter // and so must: Not (positional) so we move all pseudo DOS to the end while (match = expr.match.pseudo do.exe C (selector) {later + = match [0]; selector = selector. replace (expr. match. pseudo, "") ;}// if it is not selected in parent-child mode, select "*" selector = expr among all its descendants. relative [selector]? Selector + "*": Selector; // callback sizzle for (VAR I = 0, L = root. length; I