- 浏览: 323178 次
- 性别:
- 来自: 南昌
文章分类
最新评论
-
j_bird:
你好,想探讨下滑动窗口是怎么计算的,一条群发短信发出去,滑动窗 ...
协议研发 中移动CMPP2.0协议API -
andyliulin:
楼主,现在的magicode 生成器工具的 官网,http: ...
Mgicode 生成器正式发布 -
huazai_wow:
楼主 你只是分析了 在jquery 中 有使用到 jQu ...
jquery event trigger 分析 -
dengkanghua:
CMPP2.0中出现流量控制错误是什么引起的。有什么解决办法吗 ...
协议研发 中移动CMPP2.0协议API -
JohnHust:
[flash=200,200][/flash][url][/u ...
Jquery源码分析(一)
/* * author:prk * date:2008-08-03 * comment:analyse for Ext.DomQuery * */ /* * Ext JS Library 2.0.2 * Copyright(c) 2006-2008, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ /* * This is code is also distributed under MIT license for use * with jQuery and prototype JavaScript libraries. */ /** * @class Ext.DomQuery Provides high performance selector/xpath processing by compiling queries into reusable functions. New pseudo classes and matchers can be plugged. It works on HTML and XML documents (if a content node is passed in). <p> DomQuery supports most of the <a href="http://www.w3.org/TR/2005/WD-css3-selectors-20051215/#selectors">CSS3 selectors spec</a>, along with some custom selectors and basic XPath.</p> <p> All selectors, attribute filters and pseudos below can be combined infinitely in any order. For example "div.foo:nth-child(odd)[@foo=bar].bar:first" would be a perfectly valid selector. Node filters are processed in the order in which they appear, which allows you to optimize your queries for your document structure. </p> <h4>Element Selectors:</h4> <ul class="list"> <li> <b>*</b> any element</li> <li> <b>E</b> an element with the tag E</li> <li> <b>E F</b> All descendent elements of E that have the tag F</li> <li> <b>E > F</b> or <b>E/F</b> all direct children elements of E that have the tag F</li> <li> <b>E + F</b> all elements with the tag F that are immediately preceded by an element with the tag E</li> <li> <b>E ~ F</b> all elements with the tag F that are preceded by a sibling element with the tag E</li> </ul> <h4>Attribute Selectors:</h4> <p>The use of @ and quotes are optional. For example, div[@foo='bar'] is also a valid attribute selector.</p> <ul class="list"> <li> <b>E[foo]</b> has an attribute "foo"</li> <li> <b>E[foo=bar]</b> has an attribute "foo" that equals "bar"</li> <li> <b>E[foo^=bar]</b> has an attribute "foo" that starts with "bar"</li> <li> <b>E[foo$=bar]</b> has an attribute "foo" that ends with "bar"</li> <li> <b>E[foo*=bar]</b> has an attribute "foo" that contains the substring "bar"</li> <li> <b>E[foo%=2]</b> has an attribute "foo" that is evenly divisible by 2</li> <li> <b>E[foo!=bar]</b> has an attribute "foo" that does not equal "bar"</li> </ul> <h4>Pseudo Classes:</h4> <ul class="list"> <li> <b>E:first-child</b> E is the first child of its parent</li> <li> <b>E:last-child</b> E is the last child of its parent</li> <li> <b>E:nth-child(<i>n</i>)</b> E is the <i>n</i>th child of its parent (1 based as per the spec)</li> <li> <b>E:nth-child(odd)</b> E is an odd child of its parent</li> <li> <b>E:nth-child(even)</b> E is an even child of its parent</li> <li> <b>E:only-child</b> E is the only child of its parent</li> <li> <b>E:checked</b> E is an element that is has a checked attribute that is true (e.g. a radio or checkbox) </li> <li> <b>E:first</b> the first E in the resultset</li> <li> <b>E:last</b> the last E in the resultset</li> <li> <b>E:nth(<i>n</i>)</b> the <i>n</i>th E in the resultset (1 based)</li> <li> <b>E:odd</b> shortcut for :nth-child(odd)</li> <li> <b>E:even</b> shortcut for :nth-child(even)</li> <li> <b>E:contains(foo)</b> E's innerHTML contains the substring "foo"</li> <li> <b>E:nodeValue(foo)</b> E contains a textNode with a nodeValue that equals "foo"</li> <li> <b>E:not(S)</b> an E element that does not match simple selector S</li> <li> <b>E:has(S)</b> an E element that has a descendent that matches simple selector S</li> <li> <b>E:next(S)</b> an E element whose next sibling matches simple selector S</li> <li> <b>E:prev(S)</b> an E element whose previous sibling matches simple selector S</li> </ul> <h4>CSS Value Selectors:</h4> <ul class="list"> <li> <b>E{display=none}</b> css value "display" that equals "none"</li> <li> <b>E{display^=none}</b> css value "display" that starts with "none"</li> <li> <b>E{display$=none}</b> css value "display" that ends with "none"</li> <li> <b>E{display*=none}</b> css value "display" that contains the substring "none"</li> <li> <b>E{display%=2}</b> css value "display" that is evenly divisible by 2</li> <li> <b>E{display!=none}</b> css value "display" that does not equal "none"</li> </ul> * @singleton */ /* Element Node.ELEMENT_NODE 1 Text Node.TEXT_NODE 3 Document Node.DOCUMENT_NODE 9 Comment Node.COMMENT_NODE 8 DocumentFragment Node.DOCUMENT_FRAGMENT_NODE 11 Attr Node.ATTRIBUTE_NODE 2 */ Ext.DomQuery = function(){ var cache = {}, simpleCache = {}, valueCache = {}; var nonSpace = /\S/; var trimRe = /^\s+|\s+$/g; //{2} var tplRe = /\{(\d+)\}/g; //' [/>+~] ' | ' ' | '' var modeRe = /^(\s?[\/>+~]\s?|\s|$)/; // '#xxx'|'*'|p|a var tagTokenRe = /^(#)?([\w-\*]+)/; //3 n+ 3 not digit var nthRe = /(\d*)n\+?(\d*)/, nthRe2 = /\D/; //E:nth-child(n) 找到p的第index个孩子节点(element) function child(p, index){ var i = 0; var n = p.firstChild; while(n){ //nodeType == 1:Element if(n.nodeType == 1){ if(++i == index){ return n; } } n = n.nextSibling; } return null; }; //E:next(S) 找到n的下一个节点(element) function next(n){ while((n = n.nextSibling) && n.nodeType != 1); return n; }; //E:prev(S) 找到n的前一个节点(element) function prev(n){ while((n = n.previousSibling) && n.nodeType != 1); return n; }; //为节点的子节点标上顺序号,同时删除空白字符的节点 function children(d){ var n = d.firstChild, ni = -1; while(n){ var nx = n.nextSibling; //Text 类型同时文本为空 if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){ //删除空白字符的节点。FF,IE兼容 d.removeChild(n); }else{ //为节点加上index n.nodeIndex = ++ni; } n = nx; } return this; }; //c:element, v:value=class a:attr没用到 byClassName(n,null,"foo") //通过class名字在C中找class相同或相容的所有元素 function byClassName(c, a, v){ //value is not exist if(!v){ return c; } var r = [], ri = -1, cn; for(var i = 0, ci; ci = c[i]; i++){ //v在不在ci.className中? if((' '+ci.className+' ').indexOf(v) != -1){ r[++ri] = ci; } } return r; }; // n: [{tagName:div,htmlFor:xxx,className:xxx}] node //从n[0]中元素找到attr的属性值 function attrValue(n, attr){ if(!n.tagName && typeof n.length != "undefined"){ n = n[0]; } if(!n){ return null; } if(attr == "for"){ return n.htmlFor; } if(attr == "class" || attr == "className"){ return n.className; } //n可以是Element,也可以是{} return n.getAttribute(attr) || n[attr]; }; //ns ;nodes Element Selectors //通过tagName在ns中找tagName与之相同且符合mode运算条件的所有元素 function getNodes(ns, mode, tagName){ var result = [], ri = -1, cs; if(!ns){ return result; } tagName = tagName || "*"; //支持单个元素,转换成统一的数组形式,便于操作 if(typeof ns.getElementsByTagName != "undefined"){ ns = [ns];//转换成数组 } //mode不存在或为空等,返回其下所有的与tagName相同的元素 if(!mode){ for(var i = 0, ni; ni = ns[i]; i++){ //找到ni下面所有tagName的子标签 cs = ni.getElementsByTagName(tagName); //把找到的所有cs的Element存在result for(var j = 0, ci; ci = cs[j]; j++){ result[++ri] = ci; } } } // E > F or E/F 返回e所有tagName相同的直接子节点或全部子节点 else if(mode == "/" || mode == ">"){ var utag = tagName.toUpperCase(); for(var i = 0, ni, cn; ni = ns[i]; i++){ //ni的所有直接子节点,IE/FF兼容, cn = ni.children || ni.childNodes; for(var j = 0, cj; cj = cn[j]; j++){ //tagName相等或tagName == '*' if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){ //把找到的所有cs的Element存在result result[++ri] = cj; } } } } // E + F 返回e的第一个后续兄弟节点(element)。其tagName必须等于F或*。 else if(mode == "+"){ var utag = tagName.toUpperCase(); for(var i = 0, n; n = ns[i]; i++){ //n的下一个兄弟不是element的, while((n = n.nextSibling) && n.nodeType != 1); //找到n的下一个兄弟是Element的。 if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){ result[++ri] = n; } } } //E ~ F 返回e的所有后续兄弟节点(element),其tagName必须等于F或*。 ///E节点后面的所有兄弟节点F else if(mode == "~"){ for(var i = 0, n; n = ns[i]; i++){ //下一个兄弟存在,同时不是元素或tagName == '*'或tagName不相同 while((n = n.nextSibling) && (n.nodeType != 1 || (tagName == '*' || n.tagName.toLowerCase()!=tagName))); //下一个兄弟存在,是元素同时(tagName != '*'或tagName相同) if(n){ result[++ri] = n; } } } return result; }; function concat(a, b){ //有可能是节点集合,node Collection(getElementsByTagName), arguments is array-like . if(b.slice){ return a.concat(b); } //把b中所有元素追加到a中。 for(var i = 0, l = b.length; i < l; i++){ a[a.length] = b[i]; } return a; } //通过tagName在cs中找到与之相同tagName的所有元素 function byTag(cs, tagName){ if(cs.tagName || cs == document){ cs = [cs]; } if(!tagName){ return cs; } var r = [], ri = -1; tagName = tagName.toLowerCase(); for(var i = 0, ci; ci = cs[i]; i++){ if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){ r[++ri] = ci; } } return r; }; //通过id在cs中找到与之相同的id的所有元素 function byId(cs, attr, id){ if(cs.tagName || cs == document){ cs = [cs]; } if(!id){ return cs; } var r = [], ri = -1; for(var i = 0,ci; ci = cs[i]; i++){ if(ci && ci.id == id){ r[++ri] = ci; return r; } } return r; }; //CSS selector,and attribute Selector //通过CSS属性或自身的属性找到value相同且符合op操作关系的所有CS中元素 function byAttribute(cs, attr, value, op, custom){ var r = [], ri = -1, st = custom=="{";//表示从style中取属性做比较,CSS Value Selectors var f = Ext.DomQuery.operators[op];//Dom的操作符 for(var i = 0, ci; ci = cs[i]; i++){ var a; //找到attr的属性值 if(st){//CSS Value Selectors a = Ext.DomQuery.getStyle(ci, attr); } //纯的Attribute Selectors, else if(attr == "class" || attr == "className"){ a = ci.className; }else if(attr == "for"){ a = ci.htmlFor; }else if(attr == "href"){ a = ci.getAttribute("href", 2); }else{ a = ci.getAttribute(attr); } //如果能找到操作符,说明不是单一属性,不能彩采用找到attr的属性值来做比较 //如果能找到操作符,运算看看是否满足条件,满足的话,就表明当前的ci是要寻找的。 //如果不能找到操作符,说明采用attr的属性名来做比较 if((f && f(a, value)) || (!f && a)){ r[++ri] = ci; } } return r; }; function byPseudo(cs, name, value){ return Ext.DomQuery.pseudos[name](cs, value); }; // This is for IE MSXML which does not support expandos. // IE runs the same speed using setAttribute, however FF slows way down // and Safari completely fails so they need to continue to use expandos. var isIE = window.ActiveXObject ? true : false; // this eval is stop the compressor from // renaming the variable to something shorter eval("var batch = 30803;"); var key = 30803; //找到不重复的元素,重新组成数组返回,IE为元素加属性只能通过setAttribute function nodupIEXml(cs){ var d = ++key; cs[0].setAttribute("_nodup", d); var r = [cs[0]]; for(var i = 1, len = cs.length; i < len; i++){ var c = cs[i]; if(!c.getAttribute("_nodup") != d){ c.setAttribute("_nodup", d); r[r.length] = c; } } //去掉已经加上的属性 for(var i = 0, len = cs.length; i < len; i++){ cs[i].removeAttribute("_nodup"); } return r; } //在数组中取不重复的元素的集合 function nodup(cs){ if(!cs){ return []; } var len = cs.length, c, i, r = cs, cj, ri = -1; //elements no length or length==1 if(!len || typeof cs.nodeType != "undefined" || len == 1){ return cs; } if(isIE && typeof cs[0].selectSingleNode != "undefined"){ return nodupIEXml(cs); } var d = ++key; //cs[0]的元素有可能在Cs中多处出现,也就是说数组中不是唯一的元素。 cs[0]._nodup = d; for(i = 1; c = cs[i]; i++){ if(c._nodup != d){ c._nodup = d; }else{ r = []; //找到c._nodup = d的元素前面的所有元素,存起来 for(var j = 0; j < i; j++){ r[++ri] = cs[j]; } //跳过c._nodup==d的元素 //找到c._nodup = d的元素后面的所有元素,如果其_nodup != d,设定为d,存起来 for(j = i+1; cj = cs[j]; j++){ if(cj._nodup != d){ cj._nodup = d; r[++ri] = cj; } } return r; } } return r; } //针对IE的操作 function quickDiffIEXml(c1, c2){ var d = ++key; for(var i = 0, len = c1.length; i < len; i++){ c1[i].setAttribute("_qdiff", d); } var r = []; for(var i = 0, len = c2.length; i < len; i++){ if(c2[i].getAttribute("_qdiff") != d){ r[r.length] = c2[i]; } } for(var i = 0, len = c1.length; i < len; i++){ c1[i].removeAttribute("_qdiff"); } return r; } //返回C2中不在C1中出现过的元素 function quickDiff(c1, c2){ var len1 = c1.length; if(!len1){ return c2; } if(isIE && c1[0].selectSingleNode){ return quickDiffIEXml(c1, c2); } var d = ++key; for(var i = 0; i < len1; i++){ //因为c1[i]是元素,也就是为元素设值 c1[i]._qdiff = d; } //如果c2中元素在c1中出现过,那么值就会相等 var r = []; for(var i = 0, len = c2.length; i < len; i++){ if(c2[i]._qdiff != d){ r[r.length] = c2[i]; } } return r; } //快速通过Id找到elements function quickId(ns, mode, root, id){ if(ns == root){ var d = root.ownerDocument || root; return d.getElementById(id); } //从ns找到所有符合mode关系的元素 ns = getNodes(ns, mode, "*"); return byId(ns, null, id); } return { //获得el的style中为name的属性值 getStyle : function(el, name){ return Ext.fly(el).getStyle(name); }, /** * Compiles a selector/xpath query into a reusable function. The returned function * takes one parameter "root" (optional), which is the context node from where the query should start. * @param {String} selector The selector/xpath query * @param {String} type (optional) Either "select" (the default) or "simple" for a simple selector match * @return {Function} */ /** * div.foo:nth-child(odd)[@foo=bar]#aId{display=none} > a * * fn's content: * var f = function(root){ * var mode; ++batch; * var n = root || document; * n = getNodes(n, mode, "div"); * n = byClassName(n, null, "foo"); * n = byPseudo(n, "nth-child", "odd"); * n = byAttribute(n, "foo", "bar", "=", "["); * n = quickId(n, mode, root, "aId"); * n = byAttribute(n, "display", "none", "=", "{"); * mode=">"; * n = getNodes(n, mode, "a"); * return nodup(n); * } */ compile : function(path, type){ //默认是select type = type || "select"; var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"]; var q = path, mode, lq; var tk = Ext.DomQuery.matchers; var tklen = tk.length; var mm; // accept leading mode switch //var modeRe = /^(\s?[\/>+~]\s?|\s|$)/; element selector var lmode = q.match(modeRe); if(lmode && lmode[1]){ fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";'; q = q.replace(lmode[1], ""); } // strip leading slashes while(path.substr(0, 1)=="/"){ path = path.substr(1); } //q存在,且q发生变化 while(q && lq != q){ lq = q; // /^(#)?([\w-\*]+)/; var tm = q.match(tagTokenRe); if(type == "select"){ if(tm){ if(tm[1] == "#"){ fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");'; }else{ fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");'; } q = q.replace(tm[0], ""); } else if(q.substr(0, 1) != '@'){ //会处理到分隔开来的特殊字符开头的,如. :一些不是字符或数字的。 .xxx,或其它的。 fn[fn.length] = 'n = getNodes(n, mode, "*");'; } }else{//simple if(tm){ if(tm[1] == "#"){ //n = byId(n, null, "userNameId"); fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");'; }else{ //n = byTag(n, "p"); fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");'; } q = q.replace(tm[0], ""); } } //不是结束,也不是空格,也不是mode的符号 与主标识连在一起的。如div.foo,div:first-child while(!(mm = q.match(modeRe))){ var matched = false; /** * 这里就是实现用regexp找到符合的子项去填充生成调用的函数的参数。如下例: * 原正则表达式: re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/ * 其对应的select为:'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' * 它的 四个子项 {"([\[\{])" "([\w-]+)" "(=|.=)" "(.*?)"} * 可以把 E[foo$=bar] 分成 {"[" "foo" "$=" "bar"} 四部分 * var m = q.match(t.re)可以得出 m=['[','foo','$','bar']; * 接下来t.select.replace可以把'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' * 分成四次调用function(x, i){},其参数为{ x: 1:{2},2:{4},3:{3},4:{1} i: 1:2,2:4,3:3,4:1 } * 得出的结果:n = byAttribute(n, "foo", "bar", "$=", "["); */ for(var j = 0; j < tklen; j++){ var t = tk[j]; var m = q.match(t.re); if(m){ fn[fn.length] = t.select.replace(tplRe, function(x, i){ return m[i]; }); q = q.replace(m[0], ""); matched = true; break; } } // prevent infinite loop on bad selector if(!matched){ throw 'Error parsing selector, parsing failed at "' + q + '"'; } } //如果mode能找到值 加上:mode="~"同时remove q中找到的字符串。 if(mm[1]){ fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";'; q = q.replace(mm[1], ""); } } fn[fn.length] = "return nodup(n);\n}"; eval(fn.join("")); return f; }, /** * Selects a group of elements. * @param {String} selector The selector/xpath query (can be a comma separated list of selectors) * @param {Node} root (optional) The start of the query (defaults to document). * @return {Array} */ select : function(path, root, type){ //默认把document当做root if(!root || root == document){ root = document; } //支持root采用string id的形式 if(typeof root == "string"){ root = document.getElementById(root); } //支持多个path var paths = path.split(","); var results = []; for(var i = 0, len = paths.length; i < len; i++){ //去string前后的空格 var p = paths[i].replace(trimRe, ""); //cache 已经编译的select if(!cache[p]){ //编译 cache[p] = Ext.DomQuery.compile(p); if(!cache[p]){ throw p + " is not a valid selector"; } } //运行编译的函数 var result = cache[p](root); if(result && result != document){ results = results.concat(result); } } //去掉重复的元素 if(paths.length > 1){ return nodup(results); } return results; }, /** * Selects a single element. * @param {String} selector The selector/xpath query * @param {Node} root (optional) The start of the query (defaults to document). * @return {Element} */ //返回查询结果中的第一个。 selectNode : function(path, root){ return Ext.DomQuery.select(path, root)[0]; }, /** * Selects the value of a node, optionally replacing null with the defaultValue. * @param {String} selector The selector/xpath query * @param {Node} root (optional) The start of the query (defaults to document). * @param {String} defaultValue */ selectValue : function(path, root, defaultValue){ //trim(path) path = path.replace(trimRe, ""); //编译path if(!valueCache[path]){ valueCache[path] = Ext.DomQuery.compile(path, "select"); } //运行编译的函数 var n = valueCache[path](root); n = n[0] ? n[0] : n; //返回节点第一个孩子的节点值。 var v = (n && n.firstChild ? n.firstChild.nodeValue : null); return ((v === null||v === undefined||v==='') ? defaultValue : v); }, /** * Selects the value of a node, parsing integers and floats. * @param {String} selector The selector/xpath query * @param {Node} root (optional) The start of the query (defaults to document). * @param {Number} defaultValue * @return {Number} */ selectNumber : function(path, root, defaultValue){ var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0); return parseFloat(v); }, /** * Returns true if the passed element(s) match the passed simple selector (e.g. div.some-class or span:first-child) * @param {String/HTMLElement/Array} el An element id, element or array of elements * @param {String} selector The simple selector to test * @return {Boolean} */ is : function(el, ss){ if(typeof el == "string"){ el = document.getElementById(el); } //支持el参数为非数组的元素 var isArray = Ext.isArray(el); var result = Ext.DomQuery.filter(isArray ? el : [el], ss); return isArray ? (result.length == el.length) : (result.length > 0); }, /** * Filters an array of elements to only include matches of a simple selector (e.g. div.some-class or span:first-child) * @param {Array} el An array of elements to filter * @param {String} selector The simple selector to test * @param {Boolean} nonMatches If true, it returns the elements that DON'T match * the selector instead of the ones that match * @return {Array} */ //找到els中与ss找到els中相配或不相配的元素集合 filter : function(els, ss, nonMatches){ ss = ss.replace(trimRe, ""); if(!simpleCache[ss]){ simpleCache[ss] = Ext.DomQuery.compile(ss, "simple"); } var result = simpleCache[ss](els); return nonMatches ? quickDiff(result, els) : result; }, /** * Collection of matching regular expressions and code snippets. */ matchers : [{ re: /^\.([\w-]+)/, //div.foo select: 'n = byClassName(n, null, " {1} ");' }, { re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/, select: 'n = byPseudo(n, "{1}", "{2}");' },{ //支持CSS,属性两种形式的selector re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/, select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");' }, { re: /^#([\w-]+)/,//#aid select: 'n = byId(n, null, "{1}");' },{ re: /^@([\w-]+)/,//div@xxx select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};' } ], /** * Collection of operator comparison functions. The default operators are =, !=, ^=, $=, *=, %=, |= and ~=. * New operators can be added as long as the match the format <i>c</i>= where <i>c</i> is any character other than space, > <. */ operators : { "=" : function(a, v){ return a == v; }, "!=" : function(a, v){ return a != v; }, "^=" : function(a, v){ return a && a.substr(0, v.length) == v; }, "$=" : function(a, v){ return a && a.substr(a.length-v.length) == v; }, "*=" : function(a, v){ return a && a.indexOf(v) !== -1; }, "%=" : function(a, v){ return (a % v) == 0; }, "|=" : function(a, v){ return a && (a == v || a.substr(0, v.length+1) == v+'-'); }, "~=" : function(a, v){ return a && (' '+a+' ').indexOf(' '+v+' ') != -1; } }, /** * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array) * and the argument (if any) supplied in the selector. */ pseudos : { "first-child" : function(c){ var r = [], ri = -1, n; for(var i = 0, ci; ci = n = c[i]; i++){ while((n = n.previousSibling) && n.nodeType != 1); if(!n){ r[++ri] = ci; } } return r; }, "last-child" : function(c){ var r = [], ri = -1, n; for(var i = 0, ci; ci = n = c[i]; i++){ while((n = n.nextSibling) && n.nodeType != 1); if(!n){ r[++ri] = ci; } } return r; }, "nth-child" : function(c, a) { var r = [], ri = -1; var m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a); var f = (m[1] || 1) - 0, l = m[2] - 0; for(var i = 0, n; n = c[i]; i++){ var pn = n.parentNode; if (batch != pn._batch) { var j = 0; for(var cn = pn.firstChild; cn; cn = cn.nextSibling){ if(cn.nodeType == 1){ cn.nodeIndex = ++j; } } pn._batch = batch; } if (f == 1) { if (l == 0 || n.nodeIndex == l){ r[++ri] = n; } } else if ((n.nodeIndex + l) % f == 0){ r[++ri] = n; } } return r; }, "only-child" : function(c){ var r = [], ri = -1;; for(var i = 0, ci; ci = c[i]; i++){ if(!prev(ci) && !next(ci)){ r[++ri] = ci; } } return r; }, "empty" : function(c){ var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ var cns = ci.childNodes, j = 0, cn, empty = true; while(cn = cns[j]){ ++j; if(cn.nodeType == 1 || cn.nodeType == 3){ empty = false; break; } } if(empty){ r[++ri] = ci; } } return r; }, "contains" : function(c, v){ var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ if((ci.textContent||ci.innerText||'').indexOf(v) != -1){ r[++ri] = ci; } } return r; }, "nodeValue" : function(c, v){ var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ if(ci.firstChild && ci.firstChild.nodeValue == v){ r[++ri] = ci; } } return r; }, "checked" : function(c){ var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ if(ci.checked == true){ r[++ri] = ci; } } return r; }, "not" : function(c, ss){ return Ext.DomQuery.filter(c, ss, true); }, "any" : function(c, selectors){ var ss = selectors.split('|'); var r = [], ri = -1, s; for(var i = 0, ci; ci = c[i]; i++){ for(var j = 0; s = ss[j]; j++){ if(Ext.DomQuery.is(ci, s)){ r[++ri] = ci; break; } } } return r; }, "odd" : function(c){ return this["nth-child"](c, "odd"); }, "even" : function(c){ return this["nth-child"](c, "even"); }, "nth" : function(c, a){ return c[a-1] || []; }, "first" : function(c){ return c[0] || []; }, "last" : function(c){ return c[c.length-1] || []; }, "has" : function(c, ss){ var s = Ext.DomQuery.select; var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ if(s(ss, ci).length > 0){ r[++ri] = ci; } } return r; }, "next" : function(c, ss){ var is = Ext.DomQuery.is; var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ var n = next(ci); if(n && is(n, ss)){ r[++ri] = ci; } } return r; }, "prev" : function(c, ss){ var is = Ext.DomQuery.is; var r = [], ri = -1; for(var i = 0, ci; ci = c[i]; i++){ var n = prev(ci); if(n && is(n, ss)){ r[++ri] = ci; } } return r; } } }; }(); /** * Selects an array of DOM nodes by CSS/XPath selector. Shorthand of {@link Ext.DomQuery#select} * @param {String} path The selector/xpath query * @param {Node} root (optional) The start of the query (defaults to document). * @return {Array} * @member Ext * @method query */ Ext.query = Ext.DomQuery.select;
评论
2 楼
damoqiongqiu
2010-11-18
呃,,,不过我有2个问题,一个是var key = 30803; 另一个是eval("var batch = 30803;");
为什么key一定是从30803开始?而batch 这个东东在后面也没用上啊?求大师解答。
为什么key一定是从30803开始?而batch 这个东东在后面也没用上啊?求大师解答。
1 楼
damoqiongqiu
2010-11-18
注释得很好,再多一些说明就好了,比如nodup()这些方法,源码里面都没有注释的
发表评论
-
彻底解决Ant在Tomcat进行卸载部署undeploy时不能删除jar文件的问题
2011-04-02 14:28 4199彻底解决Ant在Tomcat进行卸载部署undeploy时不能 ... -
DomHelper源码分析
2008-08-07 20:35 2304Ext.DomHelper = function(){ ... -
dom selector 分析--1
2008-08-07 20:19 2053Ext.DomQuery和Jquery Selector的分析 ... -
Event 分析三:Ext.Util.Observalbe 源码
2008-08-04 08:32 3062/** * author:prk * date:2008- ... -
Event 分析f二:Ext.EvenManager 源码
2008-08-04 08:30 3738/** * author:prk * date:2008- ... -
Javascript Function()扩展
2008-07-30 17:42 41681、概述 ... -
Ext.template分析
2008-07-30 10:10 4358说起模板,很多人都会想起FreeMaker ... -
Ext util.XTemplate分析
2008-07-29 09:14 3245Ext.Template完成了基本 ...
相关推荐
通过这种方式,ExtJS确保了像`Ext.DomHelper`和`Ext.DomQuery`这样的工具类在整个应用中只被初始化一次,从而提高了性能并减少了内存消耗。 #### 四、单例模式的优点 - **唯一性**:确保在整个应用中只有一个实例...
**EXT源码概述** - **源代码结构**: ExtJS的源代码组织清晰,易于理解和扩展。 - **发布细节**: 在发布源码时,会包含必要的文档和示例代码,方便开发者快速上手。 #### 9. **EXT程序规划入门** - **准备工作**:...
#### EXT源码概述 深入了解ExtJS的源码可以帮助开发者更好地掌握其工作原理。ExtJS的源码组织结构清晰,分为多个模块,如`core`(核心)、`adapter`(适配器)等。通过研究源码,可以学习到如何扩展和自定义组件。 ...
- **源码结构**:Ext 框架的源码分为多个模块,每个模块负责特定的功能,例如 Core 模块包含了基础的 JavaScript 功能。 - **作用域管理**:JavaScript 中的作用域决定了变量的可见性。在 Ext 中,正确管理作用域...
- **发布Ext源码时的一些细节**: 讨论了发布EXT源码时需要注意的事项。 - **我应该从哪里开始?**: 给出了新手入门的建议。 - **适配器Adapters**: 介绍了适配器模式在EXT中的应用。 - **核心Core**: 探讨了EXT的...
EXT源码概述 ......................................................................................................... 13 揭示源代码 .......................................................................
Ext源码概述 Ext与RESTful Web Services 程序设计: 如何合理地规划一个应用程序 如何本地化ext的教程 xtype的含义 扩展Ext中的组件 扩展与插件之间的区别 扩展Ext的新手教程 Ext的类继承 从源码生成Ext 基础用法...
- **源代码结构**: 介绍了EXT源码的基本结构,包括核心模块、适配器等。 - **核心模块**: - **适配器(Adapters)**: 提供不同平台的支持。 - **核心(Core)**: 包含基本的DOM操作和事件处理等功能。 - **作用域...
源码概述章节通常会介绍EXT的架构设计、关键模块的功能及其实现方式,以及在发布源码时需要注意的细节,如依赖管理、代码结构和最佳实践等。 #### 6. EXT程序规划入门 规划一个EXT程序需要考虑多个方面,包括项目...
- **DomQuery基础**:DomQuery是EXT中用于选择DOM元素的一个强大工具。了解其基础用法可以帮助更高效地操作页面元素。 - **扩展EXT组件**:介绍如何根据实际需求定制和扩展EXT自带的组件。 - **EXT的布局(Layout...
- **源码分析**:深入分析EXT的源码结构,帮助开发者理解其内部机制。 - **细节讲解**:特别关注了在发布EXT源码过程中需要注意的细节问题,如兼容性考虑、性能优化等。 #### 10. EXT程序规划入门 - **准备工作**:...
发布Ext源码时的一些细节 12 我应该从哪里开始? 13 适配器Adapters 13 核心Core 13 Javascript中的作用域(scope) 13 事前准备 13 定义 13 正式开始 14 window对象 14 理解作用域 15 变量的可见度 15 EXT程序规划...
- **发布Ext源码时的一些细节**:EXT 在发布时会对源码进行压缩和优化,以减少文件大小,提高加载速度。 - **我应该从哪里开始**:初学者可以从研究核心组件和常用 API 开始,逐步深入理解框架的设计理念。 #### 八...