jquery-1.3.2.min-vsdoc.js
上传用户:szhf331
上传日期:2022-06-22
资源大小:1032k
文件大小:203k
源码类别:

行业应用

开发平台:

JavaScript

  1. /*
  2.  * This file has been commented to support Visual Studio Intellisense.
  3.  * You should not use this file at runtime inside the browser--it is only
  4.  * intended to be used only for design-time IntelliSense.  Please use the
  5.  * standard jQuery library for all production use.
  6.  *
  7.  * Comment version: 1.3.2b
  8.  */
  9. /* 1.3.2 汉化说明
  10. 本汉化文件部分翻译取自 1.2.6-vsdoc-cn 文件。
  11. 经本人整合、校对与增加新版帮助文档,供免费学习与个人使用,若有商业需求请联系作者。
  12. 更深的蓝, QQ621394 E-mail:topskill@gmail.com
  13. 2010-01-07:
  14. 修正: 修改了一处导致语法提示无法工作的BUG。
  15. 增加:同时发布 GBK 和 UTF-8 版本,供不同环境使用。
  16. 2009-12-21:
  17. 增加:insertAfter,insertBefore,prependTo,live,die 的翻译。
  18. 增加:innerHeight, innerWidth, outerHeight and outerWidth 的翻译。
  19. 增加:offset 的翻译。
  20. 增加:scrollLeft and scrollTop
  21. 增加:attr的详细描述。
  22. 2009-12-20:
  23. 修正:检查所有注释的param节,使其与函数声明一致。
  24. 修正:clone 的文档错误(源文档有错误)。
  25. 修正:noConflict 文档补充。
  26. 修正:toggle 的翻译。
  27. 修正:完善fadeTo的翻译。
  28. 2009-12-18:
  29. 修正:window.JQuery 文档错误。
  30. 修正:noConflict 翻译错误。
  31. 修正:$.grep 文档去除了 lambda 格式的说明(当前版本已不支持)
  32. 修正:$.map 文档去除了 lambda 格式的说明(当前版本已不支持)
  33. 修正:appendTo,prependTo,insertBefore,insertAfter 和 replaceAll 增加了对 1.3.2 的特别说明
  34. 修正:ready 函数增加了特别说明。
  35. 增加:closest 选择器的翻译。
  36. 增加:isArray 翻译。
  37. 增加:mouseenter,mouseleave 的翻译。
  38. 增加:slideDown,slideUp,slideToggle 的翻译。
  39. 增加:fadeIn,fadeOut 的翻译。
  40. TODO:setArray
  41. TODO:queue,dqueue
  42. */
  43. /* 原 1.2.6 汉化说明
  44.  *billsquall汉化
  45.  *感谢之前为API1.1 1.2汉化的各位高手,参考了不少^^
  46.  *感谢shawphy,鼓励我的好人!
  47.  *不知道有没有侵权的说法,反正这汉化仅供大家参考,版权方面不负任何责任。
  48.  *估计不会有人拿去做什么吧?不要用做商业用途,否则后果自负。
  49.  */
  50. /*
  51.  * jQuery JavaScript Library v1.3.2
  52.  * http://jquery.com/
  53.  *
  54.  * Copyright (c) 2009 John Resig
  55.  *
  56.  * Permission is hereby granted, free of charge, to any person obtaining
  57.  * a copy of this software and associated documentation files (the
  58.  * "Software"), to deal in the Software without restriction, including
  59.  * without limitation the rights to use, copy, modify, merge, publish,
  60.  * distribute, sublicense, and/or sell copies of the Software, and to
  61.  * permit persons to whom the Software is furnished to do so, subject to
  62.  * the following conditions:
  63.  *
  64.  * The above copyright notice and this permission notice shall be
  65.  * included in all copies or substantial portions of the Software.
  66.  *
  67.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  68.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  69.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  70.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  71.  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  72.  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  73.  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  74.  *
  75.  * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009)
  76.  * Revision: 6246
  77.  */
  78. (function(){
  79. var
  80. // Will speed up references to window, and allows munging its name.
  81. window = this,
  82. // Will speed up references to undefined, and allows munging its name.
  83. undefined,
  84. // Map over jQuery in case of overwrite
  85. _jQuery = window.jQuery,
  86. // Map over the $ in case of overwrite
  87. _$ = window.$,
  88. jQuery = window.jQuery = window.$ = function(selector, context) {
  89. /// <summary>
  90. /// 1: $(expression, context) - 这个函数接收一个包含 CSS 选择器的字符串,然后用这个字符串去匹配一组元素。
  91. /// 2: $(html) - 根据提供的原始 HTML 标记字符串,动态创建由 jQuery 对象包装的 DOM 元素。
  92. /// 3: $(elements) - 将一个或多个DOM元素转化为jQuery对象。
  93. /// 4: $(callback) - $(document).ready()的简写。
  94. /// </summary>
  95. /// <param name="selector" type="String">
  96. /// 1: expression - 用来查找的表达式。
  97. /// 2: html -用于动态创建DOM元素的HTML标记字符串
  98. /// 3: elements - 用于封装成jQuery对象的DOM元素
  99. /// 4: callback - 当DOM加载完成后,执行其中的函数。
  100. /// </param>
  101. /// <param name="context" type="jQuery">
  102. /// 1: context - (可选) 作为待查找的 DOM 元素集、文档或 jQuery 对象。
  103. /// </param>
  104. /// <field name="selector" Type="Object">
  105. ///     传递给JQuery的一个选择器表达式。
  106. /// </field>
  107. /// <field name="context" Type="String">
  108. ///     (可选) 作为待查找的 DOM 元素集,默认为document。
  109. /// </field>
  110. /// <returns type="jQuery" />
  111. // The jQuery object is actually just the init constructor 'enhanced'
  112. return new jQuery.fn.init( selector, context );
  113. },
  114. // A simple way to check for HTML strings or ID strings
  115. // (both of which we optimize for)
  116. quickExpr = /^[^<]*(<(.|s)+>)[^>]*$|^#([w-]+)$/,
  117. // Is it a simple selector
  118. isSimple = /^.[^:#[.,]*$/;
  119. jQuery.fn = jQuery.prototype = {
  120. init: function( selector, context ) {
  121. /// <summary>
  122. /// 1: $(expression, context) - 这个函数接收一个包含 CSS 选择器的字符串,然后用这个字符串去匹配一组元素。
  123. /// 2: $(html) - 根据提供的原始 HTML 标记字符串,动态创建由 jQuery 对象包装的 DOM 元素。
  124. /// 3: $(elements) - 将一个或多个DOM元素转化为jQuery对象。
  125. /// 4: $(callback) - $(document).ready()的简写。
  126. /// </summary>
  127. /// <param name="selector" type="String">
  128. /// 1: expression - 用来查找的表达式。
  129. /// 2: html -用于动态创建DOM元素的HTML标记字符串
  130. /// 3: elements - 用于封装成jQuery对象的DOM元素
  131. /// 4: callback - 当DOM加载完成后,执行其中的函数。
  132. /// </param>
  133. /// <param name="context" type="jQuery">
  134. /// 1: context - (可选) 作为待查找的 DOM 元素集、文档或 jQuery 对象。
  135. /// </param>
  136. /// <returns type="jQuery" />
  137. // Make sure that a selection was provided
  138. selector = selector || document;
  139. // Handle $(DOMElement)
  140. if ( selector.nodeType ) {
  141. this[0] = selector;
  142. this.length = 1;
  143. this.context = selector;
  144. return this;
  145. }
  146. // Handle HTML strings
  147. if (typeof selector === "string") {
  148. // Are we dealing with HTML string or an ID?
  149. var match = quickExpr.exec(selector);
  150. // Verify a match, and that no context was specified for #id
  151. if (match && (match[1] || !context)) {
  152. // HANDLE: $(html) -> $(array)
  153. if (match[1])
  154. selector = jQuery.clean([match[1]], context);
  155. // HANDLE: $("#id")
  156. else {
  157. var elem = document.getElementById(match[3]);
  158. // Handle the case where IE and Opera return items
  159. // by name instead of ID
  160. if (elem && elem.id != match[3])
  161. return jQuery().find(selector);
  162. // Otherwise, we inject the element directly into the jQuery object
  163. var ret = jQuery(elem || []);
  164. ret.context = document;
  165. ret.selector = selector;
  166. return ret;
  167. }
  168. // HANDLE: $(expr, [context])
  169. // (which is just equivalent to: $(content).find(expr)
  170. } else
  171. return jQuery(context).find(selector);
  172. // HANDLE: $(function)
  173. // Shortcut for document ready
  174. } else if ( jQuery.isFunction( selector ) )
  175. return jQuery( document ).ready( selector );
  176. // Make sure that old selector state is passed along
  177. if ( selector.selector && selector.context ) {
  178. this.selector = selector.selector;
  179. this.context = selector.context;
  180. }
  181. return this.setArray(jQuery.isArray( selector ) ?
  182. selector :
  183. jQuery.makeArray(selector));
  184. },
  185. // Start with an empty selector
  186. selector: "",
  187. // The current version of jQuery being used
  188. jquery: "1.3.2",
  189. // The number of elements contained in the matched element set
  190. size: function() {
  191. /// <summary>
  192. /// 当前已匹配的元素数量。
  193. /// Part of Core
  194. /// </summary>
  195. /// <returns type="Number" />
  196. return this.length;
  197. },
  198. // Get the Nth element in the matched element set OR
  199. // Get the whole matched element set as a clean array
  200. get: function( num ) {
  201. /// <summary>
  202. /// 获取匹配集中的一个元素。
  203. /// Part of Core
  204. /// </summary>
  205. /// <returns type="Element" />
  206. /// <param name="num" type="Number">
  207. /// 要获取的元素的数字索引。
  208. /// </param>
  209. return num == undefined ?
  210. // Return a 'clean' array
  211. Array.prototype.slice.call( this ) :
  212. // Return just the object
  213. this[ num ];
  214. },
  215. // Take an array of elements and push it onto the stack
  216. // (returning the new matched element set)
  217. pushStack: function( elems, name, selector ) {
  218. /// <summary>
  219. /// Set the jQuery object to an array of elements, while maintaining
  220. /// the stack.
  221. /// Part of Core
  222. /// </summary>
  223. /// <returns type="jQuery" />
  224. /// <param name="elems" type="Elements">
  225. /// An array of elements
  226. /// </param>
  227. // Build a new jQuery matched element set
  228. var ret = jQuery( elems );
  229. // Add the old object onto the stack (as a reference)
  230. ret.prevObject = this;
  231. ret.context = this.context;
  232. if ( name === "find" )
  233. ret.selector = this.selector + (this.selector ? " " : "") + selector;
  234. else if ( name )
  235. ret.selector = this.selector + "." + name + "(" + selector + ")";
  236. // Return the newly-formed element set
  237. return ret;
  238. },
  239. // Force the current matched set of elements to become
  240. // the specified array of elements (destroying the stack in the process)
  241. // You should use pushStack() in order to do this, but maintain the stack
  242. setArray: function( elems ) {
  243. /// <summary>
  244. /// Set the jQuery object to an array of elements. This operation is
  245. /// completely destructive - be sure to use .pushStack() if you wish to maintain
  246. /// the jQuery stack.
  247. /// Part of Core
  248. /// </summary>
  249. /// <returns type="jQuery" />
  250. /// <param name="elems" type="Elements">
  251. /// An array of elements
  252. /// </param>
  253. // Resetting the length to 0, then using the native Array push
  254. // is a super-fast way to populate an object with array-like properties
  255. this.length = 0;
  256. Array.prototype.push.apply( this, elems );
  257. return this;
  258. },
  259. // Execute a callback for every element in the matched set.
  260. // (You can seed the arguments with an array of args, but this is
  261. // only used internally.)
  262. each: function( callback, args ) {
  263. /// <summary>
  264. /// 以每一个匹配的元素作为上下文来执行一个函数。
  265. /// 意味着,每次执行传递进来的函数时,
  266. /// 函数中的this关键字都指向一个不同的DOM元素
  267. /// (每次都是一个不同的匹配元素)。
  268. /// 而且,在每次执行函数时,
  269. /// 都会给函数传递一个表示作为执行环境的元素在匹配的元素集合中所处位置的数字值作为参数
  270. /// (从零开始的整形)。
  271. /// </summary>
  272. /// <returns type="jQuery" />
  273. /// <param name="callback" type="Function">
  274. /// 对于每个匹配的元素所要执行的函数
  275. /// </param>
  276. return jQuery.each( this, callback, args );
  277. },
  278. // Determine the position of an element within
  279. // the matched set of elements
  280. index: function( elem ) {
  281. /// <summary>
  282. /// 搜索与参数表示的对象匹配的元素,
  283. /// 并返回相应元素的索引值值。
  284. /// 如果找到了匹配的元素,从0开始返回;如果没有找到匹配的元素,返回-1。
  285. /// Part of Core
  286. /// </summary>
  287. /// <returns type="Number" />
  288. /// <param name="elem" type="Element">
  289. /// 要搜索的对象
  290. /// </param>
  291. // Locate the position of the desired element
  292. return jQuery.inArray(
  293. // If it receives a jQuery object, the first element is used
  294. elem && elem.jquery ? elem[0] : elem
  295. , this );
  296. },
  297. attr: function( name, value, type ) {
  298. /// <summary>
  299. /// 1. attr(name) 获取第一个匹配元素的指定名字的属性值。
  300. /// 2. attr(properties) 通过一个字典参数为集合设置多个属性值。
  301. /// 3. attr( key, value ) 为集合设置一个属性。
  302. /// 4. attr( key, fn ) 不提供值,而是提供一个回调函数,把函数的结果设置为属性值。
  303. /// Part of DOM/Attributes
  304. /// </summary>
  305. /// <returns type="jQuery" />
  306. /// <param name="name" type="String">
  307. /// 属性名称
  308. /// </param>
  309. /// <param name="value" type="Function">
  310. /// 返回值的函数 范围:当前元素, 参数: 当前元素的索引值
  311. /// </param>
  312. var options = name;
  313. // Look for the case where we're accessing a style value
  314. if ( typeof name === "string" )
  315. if ( value === undefined )
  316. return this[0] && jQuery[ type || "attr" ]( this[0], name );
  317. else {
  318. options = {};
  319. options[ name ] = value;
  320. }
  321. // Check to see if we're setting style values
  322. return this.each(function(i){
  323. // Set all the styles
  324. for ( name in options )
  325. jQuery.attr(
  326. type ?
  327. this.style :
  328. this,
  329. name, jQuery.prop( this, options[ name ], type, i, name )
  330. );
  331. });
  332. },
  333. css: function( key, value ) {
  334. /// <summary>
  335. /// 在所有匹配的元素中,设置一个样式属性的值。
  336. /// 数字将自动转化为像素值
  337. /// Part of CSS
  338. /// </summary>
  339. /// <returns type="jQuery" />
  340. /// <param name="key" type="String">
  341. /// 属性名
  342. /// </param>
  343. /// <param name="value" type="String">
  344. /// 属性值
  345. /// </param>
  346. // ignore negative width and height values
  347. if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
  348. value = undefined;
  349. return this.attr( key, value, "curCSS" );
  350. },
  351. text: function( text ) {
  352. /// <summary>
  353. /// 设置所有匹配元素的文本内容
  354. /// 与 html() 类似, 但将编码 HTML (将 "<" 和 ">" 替换成相应的HTML实体)。
  355. /// Part of DOM/Attributes
  356. /// </summary>
  357. /// <returns type="String" />
  358. /// <param name="text" type="String">
  359. /// 用于设置元素内容的文本
  360. /// </param>
  361. if ( typeof text !== "object" && text != null )
  362. return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );
  363. var ret = "";
  364. jQuery.each( text || this, function(){
  365. jQuery.each( this.childNodes, function(){
  366. if ( this.nodeType != 8 )
  367. ret += this.nodeType != 1 ?
  368. this.nodeValue :
  369. jQuery.fn.text( [ this ] );
  370. });
  371. });
  372. return ret;
  373. },
  374. wrapAll: function( html ) {
  375. /// <summary>
  376. /// 将所有匹配的元素用单个元素包裹起来
  377. /// 这于 '.wrap()' 是不同的,
  378. /// '.wrap()'为每一个匹配的元素都包裹一次。
  379. /// 这种包装对于在文档中插入额外的结构化标记最有用,
  380. /// 而且它不会破坏原始文档的语义品质。
  381. /// 这个函数的原理是检查提供的第一个元素并在它的代码结构中找到最上层的祖先元素--这个祖先元素就是包装元素。
  382. /// Part of DOM/Manipulation
  383. /// </summary>
  384. /// <returns type="jQuery" />
  385. /// <param name="html" type="Element">
  386. /// HTML标记代码字符串,用于动态生成元素并包装目标元素
  387. /// </param>
  388. if ( this[0] ) {
  389. // The elements to wrap the target around
  390. var wrap = jQuery( html, this[0].ownerDocument ).clone();
  391. if ( this[0].parentNode )
  392. wrap.insertBefore( this[0] );
  393. wrap.map(function(){
  394. var elem = this;
  395. while ( elem.firstChild )
  396. elem = elem.firstChild;
  397. return elem;
  398. }).append(this);
  399. }
  400. return this;
  401. },
  402. wrapInner: function( html ) {
  403. /// <summary>
  404. /// 将每一个匹配的元素的子内容(包括文本节点)用一个HTML结构包裹起来。
  405. /// </summary>
  406. /// <param name="html" type="String">
  407. /// HTML标记代码字符串,用于动态生成元素并包装目标元素
  408. /// </param>
  409. /// <returns type="jQuery" />
  410. return this.each(function(){
  411. jQuery( this ).contents().wrapAll( html );
  412. });
  413. },
  414. wrap: function( html ) {
  415. /// <summary>
  416. /// 把所有匹配的元素用其他元素的结构化标记包裹起来。
  417. /// 这种包装对于在文档中插入额外的结构化标记最有用,
  418. /// 而且它不会破坏原始文档的语义品质。
  419. /// 这个函数的原理是检查提供的第一个元素
  420. /// (它是由所提供的HTML标记代码动态生成的),
  421. /// 并在它的代码结构中找到最上层的祖先元素--这个祖先元素就是包裹元素。
  422. /// 当HTML标记代码中的元素包含文本时无法使用这个函数。
  423. /// 因此,如果要添加文本应该在包裹完成之后再行添加。
  424. /// Part of DOM/Manipulation
  425. /// </summary>
  426. /// <returns type="jQuery" />
  427. /// <param name="html" type="Element">
  428. /// HTML标记代码字符串,用于动态生成元素并包裹目标元素
  429. /// </param>
  430. return this.each(function(){
  431. jQuery( this ).wrapAll( html );
  432. });
  433. },
  434. append: function(content) {
  435. /// <summary>
  436. /// 向每个匹配的元素内部追加内容。
  437. /// 这个操作与对指定的元素执行appendChild方法,
  438. /// 将它们添加到文档中的情况类似。
  439. /// Part of DOM/Manipulation
  440. /// </summary>
  441. /// <returns type="jQuery" />
  442. /// <param name="content" type="Content">
  443. /// 要追加到目标中的内容
  444. /// </param>
  445. return this.domManip(arguments, true, function(elem){
  446. if (this.nodeType == 1)
  447. this.appendChild( elem );
  448. });
  449. },
  450. prepend: function(content) {
  451. /// <summary>
  452. /// 向每个匹配的元素内部前置内容。
  453. /// 这是向所有匹配元素内部的开始处插入内容的最佳方式。
  454. /// Part of DOM/Manipulation
  455. /// </summary>
  456. /// <returns type="jQuery" />
  457. /// <param name="content" type="Content">
  458. /// 要插入到目标元素内部前端的内容
  459. /// </param>
  460. return this.domManip(arguments, true, function(elem){
  461. if (this.nodeType == 1)
  462. this.insertBefore( elem, this.firstChild );
  463. });
  464. },
  465. before: function(content) {
  466. /// <summary>
  467. /// 在每个匹配的元素之前插入内容。
  468. /// Part of DOM/Manipulation
  469. /// </summary>
  470. /// <returns type="jQuery" />
  471. /// <param name="content" type="Content">
  472. /// 在所有段落之前插入一些HTML标记代码。
  473. /// </param>
  474. return this.domManip(arguments, false, function(elem){
  475. this.parentNode.insertBefore( elem, this );
  476. });
  477. },
  478. after: function(content) {
  479. /// <summary>
  480. /// 在每个匹配的元素之后插入内容。
  481. /// Part of DOM/Manipulation
  482. /// </summary>
  483. /// <returns type="jQuery" />
  484. /// <param name="content" type="Content">
  485. /// 插入到每个目标后的内容
  486. /// </param>
  487. return this.domManip(arguments, false, function(elem){
  488. this.parentNode.insertBefore( elem, this.nextSibling );
  489. });
  490. },
  491. end: function() {
  492. /// <summary>
  493. /// 回到最近的一个"破坏性"操作之前。
  494. /// 即,将匹配的元素列表变为前一次的状态。
  495. /// 如果之前没有破坏性操作,则返回一个空集。
  496. /// 所谓的"破坏性"就是指任何改变所匹配的jQuery元素的操作。
  497. ///     这包括在 Traversing 中任何返回一个jQuery对象的函数--'add', 'andSelf', 'children', 'filter'
  498. ///     , 'find', 'map', 'next', 'nextAll', 'not', 'parent', 'parents', 'prev', 'prevAll'
  499. ///     , 'siblings' and 'slice'--再加上 Manipulation 中的 'clone'。
  500. /// Part of DOM/Traversing
  501. /// </summary>
  502. /// <returns type="jQuery" />
  503. return this.prevObject || jQuery( [] );
  504. },
  505. // For internal use only.
  506. // Behaves like an Array's method, not like a jQuery method.
  507. push: [].push,
  508. sort: [].sort,
  509. splice: [].splice,
  510. find: function( selector ) {
  511. /// <summary>
  512. /// 搜索所有与指定表达式匹配的元素。
  513. /// 这个函数是找出正在处理的元素的后代元素的好方法。
  514. /// 所有搜索都依靠jQuery表达式来完成。
  515. /// 这个表达式可以使用CSS1-3的选择器,或简单的XPATH语法来写。
  516. /// Part of DOM/Traversing
  517. /// </summary>
  518. /// <returns type="jQuery" />
  519. /// <param name="selector" type="String">
  520. /// 用于查找的表达式
  521. /// </param>
  522. /// <returns type="jQuery" />
  523. if ( this.length === 1 ) {
  524. var ret = this.pushStack( [], "find", selector );
  525. ret.length = 0;
  526. jQuery.find( selector, this[0], ret );
  527. return ret;
  528. } else {
  529. return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){
  530. return jQuery.find( selector, elem );
  531. })), "find", selector );
  532. }
  533. },
  534. clone: function( events ) {
  535. /// <summary>
  536. /// 克隆匹配的DOM元素并且选中这些克隆的副本。
  537. /// 在想把DOM文档中元素的副本添加到其他位置时这个函数非常有用。
  538. /// Part of DOM/Manipulation
  539. /// </summary>
  540. /// <returns type="jQuery" />
  541. /// <param name="events" type="Boolean" optional="true">
  542. /// (可选) 是否拷贝元素附加的事件,默认为不拷贝。
  543. /// </param>
  544. // Do the clone
  545. var ret = this.map(function(){
  546. if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {
  547. // IE copies events bound via attachEvent when
  548. // using cloneNode. Calling detachEvent on the
  549. // clone will also remove the events from the orignal
  550. // In order to get around this, we use innerHTML.
  551. // Unfortunately, this means some modifications to
  552. // attributes in IE that are actually only stored
  553. // as properties will not be copied (such as the
  554. // the name attribute on an input).
  555. var html = this.outerHTML;
  556. if ( !html ) {
  557. var div = this.ownerDocument.createElement("div");
  558. div.appendChild( this.cloneNode(true) );
  559. html = div.innerHTML;
  560. }
  561. return jQuery.clean([html.replace(/ jQueryd+="(?:d+|null)"/g, "").replace(/^s*/, "")])[0];
  562. } else
  563. return this.cloneNode(true);
  564. });
  565. // Copy the events from the original to the clone
  566. if ( events === true ) {
  567. var orig = this.find("*").andSelf(), i = 0;
  568. ret.find("*").andSelf().each(function(){
  569. if ( this.nodeName !== orig[i].nodeName )
  570. return;
  571. var events = jQuery.data( orig[i], "events" );
  572. for ( var type in events ) {
  573. for ( var handler in events[ type ] ) {
  574. jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );
  575. }
  576. }
  577. i++;
  578. });
  579. }
  580. // Return the cloned set
  581. return ret;
  582. },
  583. filter: function( selector ) {
  584. /// <summary>
  585. /// 筛选出与指定函数返回值匹配的元素集合
  586. /// 这个函数内部将对每个对象计算一次 (正如 '$.each').
  587. /// 如果调用的函数返回false则这个元素被删除,否则就会保留。
  588. /// })
  589. /// Part of DOM/Traversing
  590. /// </summary>
  591. /// <returns type="jQuery" />
  592. /// <param name="selector" type="Function">
  593. /// 传递进filter的函数
  594. /// </param>
  595. /// <returns type="jQuery" />
  596. return this.pushStack(
  597. jQuery.isFunction( selector ) &&
  598. jQuery.grep(this, function(elem, i){
  599. return selector.call( elem, i );
  600. }) ||
  601. jQuery.multiFilter( selector, jQuery.grep(this, function(elem){
  602. return elem.nodeType === 1;
  603. }) ), "filter", selector );
  604. },
  605. closest: function( selector ) {
  606. /// <summary>
  607. /// 返回匹配选择器,并且与起始节点最靠近的父级节点,起始节点也会被判断。
  608. /// </summary>
  609. /// <returns type="jQuery" />
  610. /// <param name="selector" type="Function">
  611. /// 用于筛选的表达式。
  612. /// </param>
  613. /// <returns type="jQuery" />
  614. var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null,
  615. closer = 0;
  616. return this.map(function(){
  617. var cur = this;
  618. while ( cur && cur.ownerDocument ) {
  619. if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) {
  620. jQuery.data(cur, "closest", closer);
  621. return cur;
  622. }
  623. cur = cur.parentNode;
  624. closer++;
  625. }
  626. });
  627. },
  628. not: function( selector ) {
  629. /// <summary>
  630. /// 将元素集合中所有与指定元素匹配的元素删除。
  631. /// 这个方法被用来删除一个jQuery对象中一个或多个元素。
  632. /// Part of DOM/Traversing
  633. /// </summary>
  634. /// <param name="selector" type="jQuery">
  635. /// jQuery对象中一组要被删除的元素。
  636. /// </param>
  637. /// <returns type="jQuery" />
  638. if ( typeof selector === "string" )
  639. // test special case where just one selector is passed in
  640. if ( isSimple.test( selector ) )
  641. return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector );
  642. else
  643. selector = jQuery.multiFilter( selector, this );
  644. var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
  645. return this.filter(function() {
  646. return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
  647. });
  648. },
  649. add: function( selector ) {
  650. /// <summary>
  651. /// 把与表达式匹配的元素添加到jQuery对象中。
  652. /// 这个函数可以用于连接分别与两个表达式匹配的元素结果集。
  653. /// Part of DOM/Traversing
  654. /// </summary>
  655. /// <param name="selector" type="Element">
  656. /// 一个或多个要添加的元素。
  657. /// </param>
  658. /// <returns type="jQuery" />
  659. return this.pushStack( jQuery.unique( jQuery.merge(
  660. this.get(),
  661. typeof selector === "string" ?
  662. jQuery( selector ) :
  663. jQuery.makeArray( selector )
  664. )));
  665. },
  666. is: function( selector ) {
  667. /// <summary>
  668. /// 用一个表达式来检查当前选择的元素集合,
  669. /// 如果其中至少有一个元素符合这个给定的表达式就返回true。
  670. /// 如果没有元素符合,或者表达式无效,都返回'false'.
  671. /// 'filter' 内部实际也是在调用这个函数,
  672. /// 所以,filter()函数原有的规则在这里也适用。
  673. /// Part of DOM/Traversing
  674. /// </summary>
  675. /// <returns type="Boolean" />
  676. /// <param name="selector" type="String">
  677. ///  用于筛选的表达式
  678. /// </param>
  679. return !!selector && jQuery.multiFilter( selector, this ).length > 0;
  680. },
  681. hasClass: function( selector ) {
  682. /// <summary>
  683. /// 检查当前的元素是否含有某个特定的类,如果有,则返回true。这其实就是 is("." + class)。
  684. /// </summary>
  685. /// <param name="selector" type="String">用于匹配的类名</param>
  686. /// <returns type="Boolean">如果有,则返回true,否则返回false.</returns>
  687. return !!selector && this.is( "." + selector );
  688. },
  689. val: function( value ) {
  690. /// <summary>
  691. /// 设置每一个匹配元素的值。在 jQuery 1.2, 这也可以为select元件赋值
  692. /// Part of DOM/Attributes
  693. /// </summary>
  694. /// <returns type="jQuery" />
  695. /// <param name="value" type="String">
  696. ///  要设置的值。
  697. /// </param>
  698. if ( value === undefined ) {
  699. var elem = this[0];
  700. if ( elem ) {
  701. if( jQuery.nodeName( elem, 'option' ) )
  702. return (elem.attributes.value || {}).specified ? elem.value : elem.text;
  703. // We need to handle select boxes special
  704. if ( jQuery.nodeName( elem, "select" ) ) {
  705. var index = elem.selectedIndex,
  706. values = [],
  707. options = elem.options,
  708. one = elem.type == "select-one";
  709. // Nothing was selected
  710. if ( index < 0 )
  711. return null;
  712. // Loop through all the selected options
  713. for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
  714. var option = options[ i ];
  715. if ( option.selected ) {
  716. // Get the specifc value for the option
  717. value = jQuery(option).val();
  718. // We don't need an array for one selects
  719. if ( one )
  720. return value;
  721. // Multi-Selects return an array
  722. values.push( value );
  723. }
  724. }
  725. return values;
  726. }
  727. // Everything else, we just grab the value
  728. return (elem.value || "").replace(/r/g, "");
  729. }
  730. return undefined;
  731. }
  732. if ( typeof value === "number" )
  733. value += '';
  734. return this.each(function(){
  735. if ( this.nodeType != 1 )
  736. return;
  737. if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) )
  738. this.checked = (jQuery.inArray(this.value, value) >= 0 ||
  739. jQuery.inArray(this.name, value) >= 0);
  740. else if ( jQuery.nodeName( this, "select" ) ) {
  741. var values = jQuery.makeArray(value);
  742. jQuery( "option", this ).each(function(){
  743. this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
  744. jQuery.inArray( this.text, values ) >= 0);
  745. });
  746. if ( !values.length )
  747. this.selectedIndex = -1;
  748. } else
  749. this.value = value;
  750. });
  751. },
  752. html: function( value ) {
  753. /// <summary>
  754. /// 设置每一个匹配元素的html内容。
  755. /// 这个函数不能用于XML文档。但可以用于XHTML文档。
  756. /// Part of DOM/Attributes
  757. /// </summary>
  758. /// <returns type="jQuery" />
  759. /// <param name="value" type="String">
  760. ///  用于设定HTML内容的值
  761. /// </param>
  762. return value === undefined ?
  763. (this[0] ?
  764. this[0].innerHTML.replace(/ jQueryd+="(?:d+|null)"/g, "") :
  765. null) :
  766. this.empty().append( value );
  767. },
  768. replaceWith: function( value ) {
  769. /// <summary>
  770. /// 将所有匹配的元素替换成指定的HTML或DOM元素。
  771. /// </summary>
  772. /// <param name="value" type="String">
  773. /// 用于将匹配元素替换掉的内容
  774. /// </param>
  775. /// <returns type="jQuery">刚替换的元素</returns>
  776. return this.after( value ).remove();
  777. },
  778. eq: function( i ) {
  779. /// <summary>
  780. /// 匹配一个给定索引值的元素。
  781. /// 从 0 开始计数
  782. /// Part of Core
  783. /// </summary>
  784. /// <returns type="jQuery" />
  785. /// <param name="i" type="Number">
  786. /// 你想要的那个元素的索引值
  787. /// </param>
  788. return this.slice( i, +i + 1 );
  789. },
  790. slice: function(start, end) {
  791. /// <summary>
  792. /// 选取一个匹配的子集。与原来的slice方法类似。
  793. /// </summary>
  794. /// <param name="start" type="Number" integer="true">开始选取子集的位置。(从0开始,负数是从集合的尾部开始选起)</param>
  795. /// <param name="end" optional="true" type="Number" integer="true"> (可选) 结束选取自己的位置,
  796. /// 如果不指定,则就是本身的结尾。</param>
  797. /// <returns type="jQuery">被选择的元素</returns>
  798. return this.pushStack( Array.prototype.slice.apply( this, arguments ),
  799. "slice", Array.prototype.slice.call(arguments).join(",") );
  800. },
  801. map: function( callback ) {
  802. /// <summary>
  803. /// 将一组元素转换成其他数组(不论是否是元素数组)
  804. /// 你可以用这个函数来建立一个列表,不论是值、属性还是CSS样式,或者其他特别形式。
  805. /// 这都可以用'$.map()'来方便的建立。
  806. /// This member is internal.
  807. /// </summary>
  808. /// <private />
  809. /// <returns type="jQuery" />
  810. return this.pushStack( jQuery.map(this, function(elem, i){
  811. return callback.call( elem, i, elem );
  812. }));
  813. },
  814. andSelf: function() {
  815. /// <summary>
  816. /// 加入上一次所选的结果到前结果集中。
  817. /// 对于筛选或查找后的元素,要加入先前所选元素时将会很有用。
  818. /// </summary>
  819. /// <returns type="jQuery" />
  820. return this.add( this.prevObject );
  821. },
  822. domManip: function( args, table, callback ) {
  823. /// <param name="args" type="Array">
  824. ///  Args
  825. /// </param>
  826. /// <param name="table" type="Boolean">
  827. ///  如果没有就在TABLE元素中插入tbody。
  828. /// </param>
  829. /// <param name="dir" type="Number">
  830. ///  如果dir小于0,则以相反的程序处理参数
  831. /// </param>
  832. /// <param name="callback" type="Function">
  833. ///  执行DOM处理的函数
  834. /// </param>
  835. /// <returns type="jQuery" />
  836. /// <summary>
  837. /// Part of Core
  838. /// </summary>
  839. if ( this[0] ) {
  840. var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(),
  841. scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ),
  842. first = fragment.firstChild;
  843. if ( first )
  844. for ( var i = 0, l = this.length; i < l; i++ )
  845. callback.call( root(this[i], first), this.length > 1 || i > 0 ?
  846. fragment.cloneNode(true) : fragment );
  847. if ( scripts )
  848. jQuery.each( scripts, evalScript );
  849. }
  850. return this;
  851. function root( elem, cur ) {
  852. return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ?
  853. (elem.getElementsByTagName("tbody")[0] ||
  854. elem.appendChild(elem.ownerDocument.createElement("tbody"))) :
  855. elem;
  856. }
  857. }
  858. };
  859. // Give the init function the jQuery prototype for later instantiation
  860. jQuery.fn.init.prototype = jQuery.fn;
  861. function evalScript( i, elem ) {
  862. /// <summary>
  863. /// This method is internal.
  864. /// </summary>
  865. /// <private />
  866. if ( elem.src )
  867. jQuery.ajax({
  868. url: elem.src,
  869. async: false,
  870. dataType: "script"
  871. });
  872. else
  873. jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );
  874. if ( elem.parentNode )
  875. elem.parentNode.removeChild( elem );
  876. }
  877. function now(){
  878. /// <summary>
  879. /// Gets the current date.
  880. /// </summary>
  881. /// <returns type="Date">The current date.</returns>
  882. return +new Date;
  883. }
  884. jQuery.extend = jQuery.fn.extend = function(_target, _prop1, _propN) {
  885. /// <summary>
  886. /// 用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
  887. /// 用于简化继承。
  888. /// jQuery.extend(settings, options);
  889. /// var settings = jQuery.extend({}, defaults, options);
  890. /// Part of JavaScript
  891. /// </summary>
  892. /// <param name="_target" type="Object">
  893. ///  待修改对象。
  894. /// </param>
  895. /// <param name="_prop1" type="Object">
  896. ///  待合并到第一个对象的对象。
  897. /// </param>
  898. /// <param name="_propN" type="Object" optional="true" parameterArray="true">
  899. ///  (可选) 待合并到第一个对象的对象。
  900. /// </param>
  901. /// <returns type="Object" />
  902. // copy reference to target object
  903. var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
  904. // Handle a deep copy situation
  905. if ( typeof target === "boolean" ) {
  906. deep = target;
  907. target = arguments[1] || {};
  908. // skip the boolean and the target
  909. i = 2;
  910. }
  911. // Handle case when target is a string or something (possible in deep copy)
  912. if ( typeof target !== "object" && !jQuery.isFunction(target) )
  913. target = {};
  914. // extend jQuery itself if only one argument is passed
  915. if ( length == i ) {
  916. target = this;
  917. --i;
  918. }
  919. for ( ; i < length; i++ )
  920. // Only deal with non-null/undefined values
  921. if ( (options = arguments[ i ]) != null )
  922. // Extend the base object
  923. for ( var name in options ) {
  924. var src = target[ name ], copy = options[ name ];
  925. // Prevent never-ending loop
  926. if ( target === copy )
  927. continue;
  928. // Recurse if we're merging object values
  929. if ( deep && copy && typeof copy === "object" && !copy.nodeType )
  930. target[ name ] = jQuery.extend( deep,
  931. // Never move original objects, clone them
  932. src || ( copy.length != null ? [ ] : { } )
  933. , copy );
  934. // Don't bring in undefined values
  935. else if ( copy !== undefined )
  936. target[ name ] = copy;
  937. }
  938. // Return the modified object
  939. return target;
  940. };
  941. // exclude the following css properties to add px
  942. var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
  943. // cache defaultView
  944. defaultView = document.defaultView || {},
  945. toString = Object.prototype.toString;
  946. jQuery.extend({
  947. noConflict: function( deep ) {
  948. /// <summary>
  949. /// 将 $ 符号还原到加载jQuery之前其他库的定义以避免冲突。
  950. /// 这个功能允许jQuery库与其他使用 $ 符号的库并存,如prototype。
  951. /// 在使用这个函数后,就只能通过'jQuery'来访问jQuery对象。
  952. /// 比如原先是 $(&quot;div p&quot;),之后必须为 jQuery(&quot;div p&quot;)。
  953. /// Part of Core
  954. /// </summary>
  955. /// <param name="deep" type="Boolean">
  956. ///  (试验)不仅还原 window.$,还将还原 window.jQuery 到先前的版本。默认只还原$
  957. /// </param>
  958. /// <returns type="undefined" />
  959. window.$ = _$;
  960. if ( deep )
  961. window.jQuery = _jQuery;
  962. return jQuery;
  963. },
  964. // See test/unit/core.js for details concerning isFunction.
  965. // Since version 1.3, DOM methods and functions like alert
  966. // aren't supported. They return false on IE (#2968).
  967. isFunction: function( obj ) {
  968. /// <summary>
  969. /// 检查一个对象是否为函数。
  970. /// </summary>
  971. /// <param name="obj" type="Object">要检查的对象</param>
  972. /// <returns type="Boolean">如果参数是一个函数返回true,否则返回false。</returns>
  973. return toString.call(obj) === "[object Function]";
  974. },
  975. isArray: function(obj) {
  976. /// <summary>
  977. /// 检查一个对象是否为数组(Array)对象。
  978. /// </summary>
  979. /// <param name="obj" type="Object">要检查的对象</param>
  980. /// <returns type="Boolean">如果参数是一个数组对象返回true,否则返回false。</returns>
  981. return toString.call(obj) === "[object Array]";
  982. },
  983. // check if an element is in a (or is an) XML document
  984. isXMLDoc: function( elem ) {
  985. /// <summary>
  986. /// 检查一个节点是否为XML文档。
  987. /// </summary>
  988. /// <param name="elem" type="Object">要测试的对象</param>
  989. /// <returns type="Boolean">如果参数是XML文档就返回true,否则返回false。</returns>
  990. return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
  991. !!elem.ownerDocument && jQuery.isXMLDoc(elem.ownerDocument);
  992. },
  993. // Evalulates a script in a global context
  994. globalEval: function( data ) {
  995. /// <summary>
  996. /// Internally evaluates a script in a global context.
  997. /// </summary>
  998. /// <private />
  999. if ( data && /S/.test(data) ) {
  1000. // Inspired by code by Andrea Giammarchi
  1001. // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
  1002. var head = document.getElementsByTagName("head")[0] || document.documentElement,
  1003. script = document.createElement("script");
  1004. script.type = "text/javascript";
  1005. if ( jQuery.support.scriptEval )
  1006. script.appendChild( document.createTextNode( data ) );
  1007. else
  1008. script.text = data;
  1009. // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
  1010. // This arises when a base node is used (#2709).
  1011. head.insertBefore( script, head.firstChild );
  1012. head.removeChild( script );
  1013. }
  1014. },
  1015. nodeName: function( elem, name ) {
  1016. /// <summary>
  1017. /// 检查指定的元素里是否有指定的DOM节点的名称。
  1018. /// </summary>
  1019. /// <param name="elem" type="Element">要检查的元素</param>
  1020. /// <param name="name" type="String">要核对的节点名称</param>
  1021. /// <returns type="Boolean">如果指定的节点名称匹配对应的节点的DOM节点名称返回true, 否则返回 false</returns>
  1022. return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
  1023. },
  1024. // args is for internal usage only
  1025. each: function( object, callback, args ) {
  1026. /// <summary>
  1027. /// 以每一个匹配的元素作为上下文来执行一个函数。
  1028. /// 意味着,每次执行传递进来的函数时,
  1029. /// 函数中的this关键字都指向一个不同的DOM元素(每次都是一个不同的匹配元素)。
  1030. /// 而且,在每次执行函数时,都会给函数传递一个表示作为执行环境的元素在匹配的元素集合中所处位置的数字值作为参数(从零开始的整形)。
  1031. /// 返回 false 将停止循环 (就像在普通的循环中使用 break)。
  1032. /// 返回 true 跳至下一个循环(就像在普通的循环中使用 continue)。
  1033. /// Part of JavaScript
  1034. /// </summary>
  1035. /// <param name="object" type="Object">
  1036. ///  要迭代的对象或数组
  1037. /// </param>
  1038. /// <param name="callback" type="Function">
  1039. ///  对于每个匹配的元素所要执行的函数
  1040. /// </param>
  1041. /// <returns type="Object" />
  1042. var name, i = 0, length = object.length;
  1043. if ( args ) {
  1044. if ( length === undefined ) {
  1045. for ( name in object )
  1046. if ( callback.apply( object[ name ], args ) === false )
  1047. break;
  1048. } else
  1049. for ( ; i < length; )
  1050. if ( callback.apply( object[ i++ ], args ) === false )
  1051. break;
  1052. // A special, fast, case for the most common use of each
  1053. } else {
  1054. if ( length === undefined ) {
  1055. for ( name in object )
  1056. if ( callback.call( object[ name ], name, object[ name ] ) === false )
  1057. break;
  1058. } else
  1059. for ( var value = object[0];
  1060. i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
  1061. }
  1062. return object;
  1063. },
  1064. prop: function( elem, value, type, i, name ) {
  1065. /// <summary>
  1066. /// This method is internal.
  1067. /// </summary>
  1068. /// <private />
  1069. // This member is not documented within the jQuery API: http://docs.jquery.com/action/edit/Internals/jQuery.prop
  1070. // Handle executable functions
  1071. if ( jQuery.isFunction( value ) )
  1072. value = value.call( elem, i );
  1073. // Handle passing in a number to a CSS property
  1074. return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ?
  1075. value + "px" :
  1076. value;
  1077. },
  1078. className: {
  1079. // internal only, use addClass("class")
  1080. add: function( elem, classNames ) {
  1081.     /// <summary>
  1082.     /// Internal use only; use addClass('class')
  1083. /// </summary>
  1084.     /// <private />
  1085. jQuery.each((classNames || "").split(/s+/), function(i, className){
  1086. if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
  1087. elem.className += (elem.className ? " " : "") + className;
  1088. });
  1089. },
  1090. // internal only, use removeClass("class")
  1091. remove: function( elem, classNames ) {
  1092.     /// <summary>
  1093.     /// Internal use only; use removeClass('class')
  1094. /// </summary>
  1095.     /// <private />
  1096. if (elem.nodeType == 1)
  1097. elem.className = classNames !== undefined ?
  1098. jQuery.grep(elem.className.split(/s+/), function(className){
  1099. return !jQuery.className.has( classNames, className );
  1100. }).join(" ") :
  1101. "";
  1102. },
  1103. // internal only, use hasClass("class")
  1104. has: function( elem, className ) {
  1105.     /// <summary>
  1106.     /// Internal use only; use hasClass('class')
  1107. /// </summary>
  1108.     /// <private />
  1109. return elem && jQuery.inArray(className, (elem.className || elem).toString().split(/s+/)) > -1;
  1110. }
  1111. },
  1112. // A method for quickly swapping in/out CSS properties to get correct calculations
  1113. swap: function( elem, options, callback ) {
  1114. /// <summary>
  1115. /// Swap in/out style options.
  1116. /// </summary>
  1117. var old = {};
  1118. // Remember the old values, and insert the new ones
  1119. for ( var name in options ) {
  1120. old[ name ] = elem.style[ name ];
  1121. elem.style[ name ] = options[ name ];
  1122. }
  1123. callback.call( elem );
  1124. // Revert the old values
  1125. for ( var name in options )
  1126. elem.style[ name ] = old[ name ];
  1127. },
  1128. css: function( elem, name, force, extra ) {
  1129. /// <summary>
  1130. /// This method is internal only.
  1131. /// </summary>
  1132. /// <private />
  1133. // This method is undocumented in jQuery API: http://docs.jquery.com/action/edit/Internals/jQuery.css
  1134. if ( name == "width" || name == "height" ) {
  1135. var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
  1136. function getWH() {
  1137. val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
  1138. if ( extra === "border" )
  1139. return;
  1140. jQuery.each( which, function() {
  1141. if ( !extra )
  1142. val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
  1143. if ( extra === "margin" )
  1144. val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;
  1145. else
  1146. val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
  1147. });
  1148. }
  1149. if ( elem.offsetWidth !== 0 )
  1150. getWH();
  1151. else
  1152. jQuery.swap( elem, props, getWH );
  1153. return Math.max(0, Math.round(val));
  1154. }
  1155. return jQuery.curCSS( elem, name, force );
  1156. },
  1157. curCSS: function( elem, name, force ) {
  1158. /// <summary>
  1159. /// This method is internal only.
  1160. /// </summary>
  1161. /// <private />
  1162. // This method is undocumented in jQuery API: http://docs.jquery.com/action/edit/Internals/jQuery.curCSS
  1163. var ret, style = elem.style;
  1164. // We need to handle opacity special in IE
  1165. if ( name == "opacity" && !jQuery.support.opacity ) {
  1166. ret = jQuery.attr( style, "opacity" );
  1167. return ret == "" ?
  1168. "1" :
  1169. ret;
  1170. }
  1171. // Make sure we're using the right name for getting the float value
  1172. if ( name.match( /float/i ) )
  1173. name = styleFloat;
  1174. if ( !force && style && style[ name ] )
  1175. ret = style[ name ];
  1176. else if ( defaultView.getComputedStyle ) {
  1177. // Only "float" is needed here
  1178. if ( name.match( /float/i ) )
  1179. name = "float";
  1180. name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();
  1181. var computedStyle = defaultView.getComputedStyle( elem, null );
  1182. if ( computedStyle )
  1183. ret = computedStyle.getPropertyValue( name );
  1184. // We should always get a number back from opacity
  1185. if ( name == "opacity" && ret == "" )
  1186. ret = "1";
  1187. } else if ( elem.currentStyle ) {
  1188. var camelCase = name.replace(/-(w)/g, function(all, letter){
  1189. return letter.toUpperCase();
  1190. });
  1191. ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];
  1192. // From the awesome hack by Dean Edwards
  1193. // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
  1194. // If we're not dealing with a regular pixel number
  1195. // but a number that has a weird ending, we need to convert it to pixels
  1196. if ( !/^d+(px)?$/i.test( ret ) && /^d/.test( ret ) ) {
  1197. // Remember the original values
  1198. var left = style.left, rsLeft = elem.runtimeStyle.left;
  1199. // Put in the new values to get a computed value out
  1200. elem.runtimeStyle.left = elem.currentStyle.left;
  1201. style.left = ret || 0;
  1202. ret = style.pixelLeft + "px";
  1203. // Revert the changed values
  1204. style.left = left;
  1205. elem.runtimeStyle.left = rsLeft;
  1206. }
  1207. }
  1208. return ret;
  1209. },
  1210. clean: function( elems, context, fragment ) {
  1211. /// <summary>
  1212. /// This method is internal only.
  1213. /// </summary>
  1214. /// <private />
  1215. // This method is undocumented in the jQuery API: http://docs.jquery.com/action/edit/Internals/jQuery.clean
  1216. context = context || document;
  1217. // !context.createElement fails in IE with an error but returns typeof 'object'
  1218. if ( typeof context.createElement === "undefined" )
  1219. context = context.ownerDocument || context[0] && context[0].ownerDocument || document;
  1220. // If a single string is passed in and it's a single tag
  1221. // just do a createElement and skip the rest
  1222. if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) {
  1223. var match = /^<(w+)s*/?>$/.exec(elems[0]);
  1224. if ( match )
  1225. return [ context.createElement( match[1] ) ];
  1226. }
  1227. var ret = [], scripts = [], div = context.createElement("div");
  1228. jQuery.each(elems, function(i, elem){
  1229. if ( typeof elem === "number" )
  1230. elem += '';
  1231. if ( !elem )
  1232. return;
  1233. // Convert html string into DOM nodes
  1234. if ( typeof elem === "string" ) {
  1235. // Fix "XHTML"-style tags in all browsers
  1236. elem = elem.replace(/(<(w+)[^>]*?)/>/g, function(all, front, tag){
  1237. return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
  1238. all :
  1239. front + "></" + tag + ">";
  1240. });
  1241. // Trim whitespace, otherwise indexOf won't work as expected
  1242. var tags = elem.replace(/^s+/, "").substring(0, 10).toLowerCase();
  1243. var wrap =
  1244. // option or optgroup
  1245. !tags.indexOf("<opt") &&
  1246. [ 1, "<select multiple='multiple'>", "</select>" ] ||
  1247. !tags.indexOf("<leg") &&
  1248. [ 1, "<fieldset>", "</fieldset>" ] ||
  1249. tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
  1250. [ 1, "<table>", "</table>" ] ||
  1251. !tags.indexOf("<tr") &&
  1252. [ 2, "<table><tbody>", "</tbody></table>" ] ||
  1253.   // <thead> matched above
  1254. (!tags.indexOf("<td") || !tags.indexOf("<th")) &&
  1255. [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
  1256. !tags.indexOf("<col") &&
  1257. [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||
  1258. // IE can't serialize <link> and <script> tags normally
  1259. !jQuery.support.htmlSerialize &&
  1260. [ 1, "div<div>", "</div>" ] ||
  1261. [ 0, "", "" ];
  1262. // Go to html and back, then peel off extra wrappers
  1263. div.innerHTML = wrap[1] + elem + wrap[2];
  1264. // Move to the right depth
  1265. while ( wrap[0]-- )
  1266. div = div.lastChild;
  1267. // Remove IE's autoinserted <tbody> from table fragments
  1268. if ( !jQuery.support.tbody ) {
  1269. // String was a <table>, *may* have spurious <tbody>
  1270. var hasBody = /<tbody/i.test(elem),
  1271. tbody = !tags.indexOf("<table") && !hasBody ?
  1272. div.firstChild && div.firstChild.childNodes :
  1273. // String was a bare <thead> or <tfoot>
  1274. wrap[1] == "<table>" && !hasBody ?
  1275. div.childNodes :
  1276. [];
  1277. for ( var j = tbody.length - 1; j >= 0 ; --j )
  1278. if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
  1279. tbody[ j ].parentNode.removeChild( tbody[ j ] );
  1280. }
  1281. // IE completely kills leading whitespace when innerHTML is used
  1282. if ( !jQuery.support.leadingWhitespace && /^s/.test( elem ) )
  1283. div.insertBefore( context.createTextNode( elem.match(/^s*/)[0] ), div.firstChild );
  1284. elem = jQuery.makeArray( div.childNodes );
  1285. }
  1286. if ( elem.nodeType )
  1287. ret.push( elem );
  1288. else
  1289. ret = jQuery.merge( ret, elem );
  1290. });
  1291. if ( fragment ) {
  1292. for ( var i = 0; ret[i]; i++ ) {
  1293. if ( jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {
  1294. scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );
  1295. } else {
  1296. if ( ret[i].nodeType === 1 )
  1297. ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );
  1298. fragment.appendChild( ret[i] );
  1299. }
  1300. }
  1301. return scripts;
  1302. }
  1303. return ret;
  1304. },
  1305. attr: function( elem, name, value ) {
  1306. /// <summary>
  1307. /// 取得第一个匹配元素的属性值。通过这个方法可以方便地从第一个匹配元素中获取一个属性的值。
  1308. /// 如果元素没有相应属性,则返回 undefined 。
  1309. /// 内部方法。
  1310. /// </summary>
  1311. /// <private />
  1312. // don't set attributes on text and comment nodes
  1313. if (!elem || elem.nodeType == 3 || elem.nodeType == 8)
  1314. return undefined;
  1315. var notxml = !jQuery.isXMLDoc( elem ),
  1316. // Whether we are setting (or getting)
  1317. set = value !== undefined;
  1318. // Try to normalize/fix the name
  1319. name = notxml && jQuery.props[ name ] || name;
  1320. // Only do all the following if this is a node (faster for style)
  1321. // IE elem.getAttribute passes even for style
  1322. if ( elem.tagName ) {
  1323. // These attributes require special treatment
  1324. var special = /href|src|style/.test( name );
  1325. // Safari mis-reports the default selected property of a hidden option
  1326. // Accessing the parent's selectedIndex property fixes it
  1327. if ( name == "selected" && elem.parentNode )
  1328. elem.parentNode.selectedIndex;
  1329. // If applicable, access the attribute via the DOM 0 way
  1330. if ( name in elem && notxml && !special ) {
  1331. if ( set ){
  1332. // We can't allow the type property to be changed (since it causes problems in IE)
  1333. if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
  1334. throw "type property can't be changed";
  1335. elem[ name ] = value;
  1336. }
  1337. // browsers index elements by id/name on forms, give priority to attributes.
  1338. if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
  1339. return elem.getAttributeNode( name ).nodeValue;
  1340. // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
  1341. // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
  1342. if ( name == "tabIndex" ) {
  1343. var attributeNode = elem.getAttributeNode( "tabIndex" );
  1344. return attributeNode && attributeNode.specified
  1345. ? attributeNode.value
  1346. : elem.nodeName.match(/(button|input|object|select|textarea)/i)
  1347. ? 0
  1348. : elem.nodeName.match(/^(a|area)$/i) && elem.href
  1349. ? 0
  1350. : undefined;
  1351. }
  1352. return elem[ name ];
  1353. }
  1354. if ( !jQuery.support.style && notxml &&  name == "style" )
  1355. return jQuery.attr( elem.style, "cssText", value );
  1356. if ( set )
  1357. // convert the value to a string (all browsers do this but IE) see #1070
  1358. elem.setAttribute( name, "" + value );
  1359. var attr = !jQuery.support.hrefNormalized && notxml && special
  1360. // Some attributes require a special call on IE
  1361. ? elem.getAttribute( name, 2 )
  1362. : elem.getAttribute( name );
  1363. // Non-existent attributes return null, we normalize to undefined
  1364. return attr === null ? undefined : attr;
  1365. }
  1366. // elem is actually elem.style ... set the style
  1367. // IE uses filters for opacity
  1368. if ( !jQuery.support.opacity && name == "opacity" ) {
  1369. if ( set ) {
  1370. // IE has trouble with opacity if it does not have layout
  1371. // Force it by setting the zoom level
  1372. elem.zoom = 1;
  1373. // Set the alpha filter to set the opacity
  1374. elem.filter = (elem.filter || "").replace( /alpha([^)]*)/, "" ) +
  1375. (parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
  1376. }
  1377. return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
  1378. (parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
  1379. "";
  1380. }
  1381. name = name.replace(/-([a-z])/ig, function(all, letter){
  1382. return letter.toUpperCase();
  1383. });
  1384. if ( set )
  1385. elem[ name ] = value;
  1386. return elem[ name ];
  1387. },
  1388. trim: function( text ) {
  1389. /// <summary>
  1390. /// 去掉字符串起始和结尾的空格。
  1391. /// Part of JavaScript
  1392. /// </summary>
  1393. /// <returns type="String" />
  1394. /// <param name="text" type="String">
  1395. /// 要去空格的字符串
  1396. /// </param>
  1397. return (text || "").replace( /^s+|s+$/g, "" );
  1398. },
  1399. makeArray: function( array ) {
  1400. /// <summary>
  1401. /// 将类数组对象转换为数组对象。
  1402. /// 类数组对象有 length 属性,其成员索引为 0 至 length - 1。实际中此函数在 jQuery 中将自动使用而无需特意转换。
  1403. /// </summary>
  1404. /// <param name="array" type="Object">要转换为数组对象的类数组对象。</param>
  1405. /// <returns type="Array" />
  1406. /// <private />
  1407. var ret = [];
  1408. if( array != null ){
  1409. var i = array.length;
  1410. // The window, strings (and functions) also have 'length'
  1411. if( i == null || typeof array === "string" || jQuery.isFunction(array) || array.setInterval )
  1412. ret[0] = array;
  1413. else
  1414. while( i )
  1415. ret[--i] = array[i];
  1416. }
  1417. return ret;
  1418. },
  1419. inArray: function( elem, array ) {
  1420. /// <summary>
  1421. /// 确定第一个参数在数组中的位置(如果没有找到则返回 -1 )。
  1422. /// </summary>
  1423. /// <param name="elem">用于在数组中查找是否存在的值</param>
  1424. /// <param name="array" type="Array">待处理数组。</param>
  1425. /// <returns type="Number" integer="true">如果找到,则从0开始累计,没有找到则返回 -1</returns>
  1426. for ( var i = 0, length = array.length; i < length; i++ )
  1427. // Use === because on IE, window == document
  1428. if ( array[ i ] === elem )
  1429. return i;
  1430. return -1;
  1431. },
  1432. merge: function( first, second ) {
  1433. /// <summary>
  1434. /// 合并两个数组。第二个数组中与第一个数组重复的元素将会被忽略。
  1435. /// Part of JavaScript
  1436. /// </summary>
  1437. /// <returns type="Array" />
  1438. /// <param name="first" type="Array">
  1439. ///  第一个要合并的数组。
  1440. /// </param>
  1441. /// <param name="second" type="Array">
  1442. ///  第二个要合并的数组。
  1443. /// </param>
  1444. // We have to loop this way because IE & Opera overwrite the length
  1445. // expando of getElementsByTagName
  1446. var i = 0, elem, pos = first.length;
  1447. // Also, we need to make sure that the correct elements are being returned
  1448. // (IE returns comment nodes in a '*' query)
  1449. if ( !jQuery.support.getAll ) {
  1450. while ( (elem = second[ i++ ]) != null )
  1451. if ( elem.nodeType != 8 )
  1452. first[ pos++ ] = elem;
  1453. } else
  1454. while ( (elem = second[ i++ ]) != null )
  1455. first[ pos++ ] = elem;
  1456. return first;
  1457. },
  1458. unique: function( array ) {
  1459. /// <summary>
  1460. /// 删除元素数组中所有的重复元素。
  1461. /// </summary>
  1462. /// <param name="array" type="Array&lt;Element&gt;">要转换的数组</param>
  1463. /// <returns type="Array&lt;Element&gt;">转换后的数组</returns>
  1464. var ret = [], done = {};
  1465. try {
  1466. for ( var i = 0, length = array.length; i < length; i++ ) {
  1467. var id = jQuery.data( array[ i ] );
  1468. if ( !done[ id ] ) {
  1469. done[ id ] = true;
  1470. ret.push( array[ i ] );
  1471. }
  1472. }
  1473. } catch( e ) {
  1474. ret = array;
  1475. }
  1476. return ret;
  1477. },
  1478. grep: function( elems, callback, inv ) {
  1479. /// <summary>
  1480. /// 使用过滤函数过滤数组元素。
  1481. /// 此函数至少传递两个参数:待过滤数组和过滤函数。
  1482. /// 过滤函数必须返回 true 以保留元素或 false 以删除元素。
  1483. /// });
  1484. /// Part of JavaScript
  1485. /// </summary>
  1486. /// <returns type="Array" />
  1487. /// <param name="elems" type="Array">
  1488. /// 待过滤数组。
  1489. /// </param>
  1490. /// <param name="callback" type="Function">
  1491. /// 此函数将处理数组每个元素。第一个参数为当前元素,第二个参数为元素索引值。
  1492. /// 此函数应返回一个布尔值。
  1493. /// fn 必须为函数对象,旧的 lambda 格式已经不再支持。
  1494. /// </param>
  1495. /// <param name="inv" type="Boolean">
  1496. /// (可选) 如果 "invert" 为 false 或为设置,则函数返回数组中由过滤函数返回 true 的元素,
  1497. /// 当"invert" 为 true,则返回过滤函数中返回 false 的元素集。
  1498. /// </param>
  1499. var ret = [];
  1500. // Go through the array, only saving the items
  1501. // that pass the validator function
  1502. for ( var i = 0, length = elems.length; i < length; i++ )
  1503. if ( !inv != !callback( elems[ i ], i ) )
  1504. ret.push( elems[ i ] );
  1505. return ret;
  1506. },
  1507. map: function( elems, callback ) {
  1508. /// <summary>
  1509. /// 将一个数组中的元素转换到另一个数组中。
  1510. /// 作为参数的转换函数会为每个数组元素调用,
  1511. /// 而且会给这个转换函数传递一个表示被转换的元素作为参数。
  1512. /// 转换函数可以返回转换后的值、null(删除数组中的项目)
  1513. /// 或一个包含值的数组,并扩展至原始数组中。
  1514. /// Part of JavaScript
  1515. /// </summary>
  1516. /// <returns type="Array" />
  1517. /// <param name="elems" type="Array">
  1518. /// 待转换数组。
  1519. /// </param>
  1520. /// <param name="callback" type="Function">
  1521. /// 为每个数组元素调用,而且会给这个转换函数传递一个表示被转换的元素作为参数。函数可返回任何值。
  1522. /// fn 必须为函数对象,旧的 lambda 格式已经不再支持。
  1523. /// </param>
  1524. var ret = [];
  1525. // Go through the array, translating each of the items to their
  1526. // new value (or values).
  1527. for ( var i = 0, length = elems.length; i < length; i++ ) {
  1528. var value = callback( elems[ i ], i );
  1529. if ( value != null )
  1530. ret[ ret.length ] = value;
  1531. }
  1532. return ret.concat.apply( [], ret );
  1533. }
  1534. });
  1535. // Use of jQuery.browser is deprecated.
  1536. // It's included for backwards compatibility and plugins,
  1537. // although they should work to migrate away.
  1538. var userAgent = navigator.userAgent.toLowerCase();
  1539. // Figure out what browser is being used
  1540. jQuery.browser = {
  1541. version: (userAgent.match( /.+(?:rv|it|ra|ie)[/: ]([d.]+)/ ) || [0,'0'])[1],
  1542. safari: /webkit/.test( userAgent ),
  1543. opera: /opera/.test( userAgent ),
  1544. msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
  1545. mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
  1546. };
  1547. // [vsdoc] The following section has been denormalized from original sources for IntelliSense.
  1548. // jQuery.each({
  1549. //  parent: function(elem){return elem.parentNode;},
  1550. //  parents: function(elem){return jQuery.dir(elem,"parentNode");},
  1551. //  next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
  1552. //  prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
  1553. //  nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
  1554. //  prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
  1555. //  siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
  1556. //  children: function(elem){return jQuery.sibling(elem.firstChild);},
  1557. //  contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
  1558. // }, function(name, fn){
  1559. //  jQuery.fn[ name ] = function( selector ) {
  1560. //  /// <summary>
  1561. // /// 取得一个包含着所有匹配元素的唯一父元素的元素集合。
  1562. // /// 你可以使用可选的表达式来筛选。
  1563. // /// Part of DOM/Traversing
  1564. //  /// </summary>
  1565. //  /// <param name="selector" type="String" optional="true">
  1566. // ///  (可选)用来筛选的表达式
  1567. //  /// </param>
  1568. //  /// <returns type="jQuery" />
  1569. //
  1570. //  var ret = jQuery.map( this, fn );
  1571. //
  1572. //  if ( selector && typeof selector == "string" )
  1573. //  ret = jQuery.multiFilter( selector, ret );
  1574. //
  1575. //  return this.pushStack( jQuery.unique( ret ), name, selector );
  1576. //  };
  1577. // });
  1578. jQuery.each({
  1579. parent: function(elem){return elem.parentNode;}
  1580. }, function(name, fn){
  1581. jQuery.fn[ name ] = function( selector ) {
  1582.   /// <summary>
  1583. /// 取得一个包含着所有匹配元素的唯一父元素的元素集合。
  1584. /// 你可以使用可选的表达式来筛选。
  1585. /// Part of DOM/Traversing
  1586.   /// </summary>
  1587.   /// <param name="selector" type="String" optional="true">
  1588. ///  (可选)用来筛选的表达式
  1589.   /// </param>
  1590.   /// <returns type="jQuery" />
  1591. var ret = jQuery.map( this, fn );
  1592. if ( selector && typeof selector == "string" )
  1593. ret = jQuery.multiFilter( selector, ret );
  1594. return this.pushStack( jQuery.unique( ret ), name, selector );
  1595. };
  1596. });
  1597. jQuery.each({
  1598. parents: function(elem){return jQuery.dir(elem,"parentNode");}
  1599. }, function(name, fn){
  1600. jQuery.fn[ name ] = function( selector ) {
  1601. /// <summary>
  1602. /// 取得一组包含唯一祖先元素的匹配元素
  1603. /// (除了根元素)
  1604. /// 你可以使用可选的表达式来筛选。
  1605. /// Part of DOM/Traversing
  1606. /// </summary>
  1607. /// <param name="selector" type="String" optional="true">
  1608. /// (可选) 用来筛选元素的表达式
  1609. /// </param>
  1610. /// <returns type="jQuery" />
  1611. var ret = jQuery.map( this, fn );
  1612. if ( selector && typeof selector == "string" )
  1613. ret = jQuery.multiFilter( selector, ret );
  1614. return this.pushStack( jQuery.unique( ret ), name, selector );
  1615. };
  1616. });
  1617. jQuery.each({
  1618. next: function(elem){return jQuery.nth(elem,2,"nextSibling");}
  1619. }, function(name, fn){
  1620. jQuery.fn[ name ] = function( selector ) {
  1621. /// <summary>
  1622. /// 取得一组包含唯一后一个兄弟元素的匹配元素
  1623. /// 它只能返回下一个子元素,而不是所有的子元素。
  1624. /// 你可以使用可选的表达式来筛选。
  1625. /// Part of DOM/Traversing
  1626. /// </summary>
  1627. /// <param name="selector" type="String" optional="true">
  1628. /// (可选) 用来筛选兄弟元素的表达式
  1629. /// </param>
  1630. /// <returns type="jQuery" />
  1631. var ret = jQuery.map( this, fn );
  1632. if ( selector && typeof selector == "string" )
  1633. ret = jQuery.multiFilter( selector, ret );
  1634. return this.pushStack( jQuery.unique( ret ), name, selector );
  1635. };
  1636. });
  1637. jQuery.each({
  1638. prev: function(elem){return jQuery.nth(elem,2,"previousSibling");}
  1639. }, function(name, fn){
  1640. jQuery.fn[ name ] = function( selector ) {
  1641. /// <summary>
  1642. /// 取得一组包含唯一前一个兄弟元素的匹配元素
  1643. /// 它只能返回前一个子元素,而不是所有的子元素
  1644. /// 你可以使用可选的表达式来筛选。
  1645. /// Part of DOM/Traversing
  1646. /// </summary>
  1647. /// <param name="selector" type="String" optional="true">
  1648. /// (可选) 用来筛选兄弟元素的表达式
  1649. /// </param>
  1650. /// <returns type="jQuery" />
  1651. var ret = jQuery.map( this, fn );
  1652. if ( selector && typeof selector == "string" )
  1653. ret = jQuery.multiFilter( selector, ret );
  1654. return this.pushStack( jQuery.unique( ret ), name, selector );
  1655. };
  1656. });
  1657. jQuery.each({
  1658. nextAll: function(elem){return jQuery.dir(elem,"nextSibling");}
  1659. }, function(name, fn){
  1660. jQuery.fn[name] = function(selector) {
  1661. /// <summary>
  1662. /// 找出当前元素后的所有兄弟元素
  1663. /// 你可以使用可选的表达式来筛选。
  1664. /// Part of DOM/Traversing
  1665. /// </summary>
  1666. /// <param name="selector" type="String" optional="true">
  1667. /// (可选) 用来筛选元素的表达式
  1668. /// </param>
  1669. /// <returns type="jQuery" />
  1670. var ret = jQuery.map( this, fn );
  1671. if ( selector && typeof selector == "string" )
  1672. ret = jQuery.multiFilter( selector, ret );
  1673. return this.pushStack( jQuery.unique( ret ), name, selector );
  1674. };
  1675. });
  1676. jQuery.each({
  1677. prevAll: function(elem){return jQuery.dir(elem,"previousSibling");}
  1678. }, function(name, fn){
  1679. jQuery.fn[ name ] = function( selector ) {
  1680. /// <summary>
  1681. /// 找出当前元素前面的所有兄弟元素
  1682. /// 你可以使用可选的表达式来筛选。
  1683. /// Part of DOM/Traversing
  1684. /// </summary>
  1685. /// <param name="selector" type="String" optional="true">
  1686. /// (可选) 用来筛选兄弟元素的表达式
  1687. /// </param>
  1688. /// <returns type="jQuery" />
  1689. var ret = jQuery.map( this, fn );
  1690. if ( selector && typeof selector == "string" )
  1691. ret = jQuery.multiFilter( selector, ret );
  1692. return this.pushStack( jQuery.unique( ret ), name, selector );
  1693. };
  1694. });
  1695. jQuery.each({
  1696. siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);}
  1697. }, function(name, fn){
  1698. jQuery.fn[ name ] = function( selector ) {
  1699. /// <summary>
  1700. /// 迭代并取得一组包含唯一所有兄弟元素的匹配元素
  1701. /// 你可以使用可选的表达式来筛选。
  1702. /// Part of DOM/Traversing
  1703. /// </summary>
  1704. /// <param name="selector" type="String" optional="true">
  1705. /// (可选) 用来筛选兄弟元素的表达式
  1706. /// </param>
  1707. /// <returns type="jQuery" />
  1708. var ret = jQuery.map( this, fn );
  1709. if ( selector && typeof selector == "string" )
  1710. ret = jQuery.multiFilter( selector, ret );
  1711. return this.pushStack( jQuery.unique( ret ), name, selector );
  1712. };
  1713. });
  1714. jQuery.each({
  1715. children: function(elem){return jQuery.sibling(elem.firstChild);}
  1716. }, function(name, fn){
  1717. jQuery.fn[ name ] = function( selector ) {
  1718. /// <summary>
  1719. /// 迭代并取得一组包含唯一所有子元素的匹配元素
  1720. /// 你可以使用可选的表达式来筛选。
  1721. /// Part of DOM/Traversing
  1722. /// </summary>
  1723. /// <param name="selector" type="String" optional="true">
  1724. /// (可选) 用来筛选子元素的表达式
  1725. /// </param>
  1726. /// <returns type="jQuery" />
  1727. var ret = jQuery.map( this, fn );
  1728. if ( selector && typeof selector == "string" )
  1729. ret = jQuery.multiFilter( selector, ret );
  1730. return this.pushStack( jQuery.unique( ret ), name, selector );
  1731. };
  1732. });
  1733. jQuery.each({
  1734. contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
  1735. }, function(name, fn){
  1736. jQuery.fn[ name ] = function( selector ) {
  1737. /// <summary>Finds all the child nodes inside the matched elements including text nodes, or the content document if the element is an iframe.</summary>
  1738. /// <returns type="jQuery" />
  1739. var ret = jQuery.map( this, fn );
  1740. if ( selector && typeof selector == "string" )
  1741. ret = jQuery.multiFilter( selector, ret );
  1742. return this.pushStack( jQuery.unique( ret ), name, selector );
  1743. };
  1744. });
  1745. // [vsdoc] The following section has been denormalized from original sources for IntelliSense.
  1746. // jQuery.each({
  1747. //  appendTo: "append",
  1748. //  prependTo: "prepend",
  1749. //  insertBefore: "before",
  1750. //  insertAfter: "after",
  1751. //  replaceAll: "replaceWith"
  1752. // }, function(name, original){
  1753. //  jQuery.fn[ name ] = function() {
  1754. //  var args = arguments;
  1755. //
  1756. //  return this.each(function(){
  1757. //  for ( var i = 0, length = args.length; i < length; i++ )
  1758. //  jQuery( args[ i ] )[ original ]( this );
  1759. //  });
  1760. //  };
  1761. // });
  1762. jQuery.fn.appendTo = function( selector ) {
  1763. /// <summary>
  1764. /// 把所有匹配的元素插入到另一个、指定的元素元素集合的结束标记前。
  1765. /// jQuery 1.3.2 会返回所有已插入的元素。
  1766. /// $(源集合).appendTo(目标集合); 会把源集合的每个元素依次插入目标集合每个元素的结束标记之前。
  1767. /// Part of DOM/Manipulation
  1768. /// </summary>
  1769. /// <param name="selector" type="Selector">
  1770. /// 要插入的目标集合
  1771. /// </param>
  1772. /// <returns type="jQuery" />
  1773. var ret = [], insert = jQuery( selector );
  1774. for ( var i = 0, l = insert.length; i < l; i++ ) {
  1775. var elems = (i > 0 ? this.clone(true) : this).get();
  1776. jQuery.fn[ "append" ].apply( jQuery(insert[i]), elems );
  1777. ret = ret.concat( elems );
  1778. }
  1779. return this.pushStack( ret, "appendTo", selector );
  1780. };
  1781. jQuery.fn.prependTo = function( selector ) {
  1782. /// <summary>
  1783. /// 把所有匹配的元素插入到另一个、指定的元素元素集合的开始标记后。
  1784. /// jQuery 1.3.2 会返回所有已插入的元素。
  1785. /// $(源集合).prependTo(目标集合); 会把源集合的每个元素依次插入目标集合每个元素的开始标记之后。
  1786. /// Part of DOM/Manipulation
  1787. /// </summary>
  1788. /// <param name="selector" type="Selector">
  1789. /// 要插入的目标集合
  1790. /// </param>
  1791. /// <returns type="jQuery" />
  1792. var ret = [], insert = jQuery( selector );
  1793. for ( var i = 0, l = insert.length; i < l; i++ ) {
  1794. var elems = (i > 0 ? this.clone(true) : this).get();
  1795. jQuery.fn[ "prepend" ].apply( jQuery(insert[i]), elems );
  1796. ret = ret.concat( elems );
  1797. }
  1798. return this.pushStack( ret, "prependTo", selector );
  1799. };
  1800. jQuery.fn.insertBefore = function( selector ) {
  1801. /// <summary>
  1802. /// 把所有匹配的元素插入到另一个、指定的元素元素集合的前面。
  1803. /// jQuery 1.3.2 会返回所有已插入的元素。
  1804. /// $(源集合).insertBefore(目标集合); 会把源集合的每个元素依次插入目标集合每个元素之前。
  1805. /// Part of DOM/Manipulation
  1806. /// </summary>
  1807. /// <param name="selector" type="String">
  1808. /// 要插入的目标集合
  1809. /// </param>
  1810. /// <returns type="jQuery" />
  1811. var ret = [], insert = jQuery( selector );
  1812. for ( var i = 0, l = insert.length; i < l; i++ ) {
  1813. var elems = (i > 0 ? this.clone(true) : this).get();
  1814. jQuery.fn[ "before" ].apply( jQuery(insert[i]), elems );
  1815. ret = ret.concat( elems );
  1816. }
  1817. return this.pushStack( ret, "insertBefore", selector );
  1818. };
  1819. jQuery.fn.insertAfter = function( selector ) {
  1820. /// <summary>
  1821. /// 把所有匹配的元素插入到另一个、指定的元素元素集合的后面。
  1822. /// jQuery 1.3.2 会返回所有已插入的元素。
  1823. /// $(源集合).insertBefore(目标集合); 会把源集合的每个元素依次插入目标集合每个元素之后。
  1824. /// </summary>
  1825. /// <param name="selector" type="String">
  1826. /// 要插入的目标集合
  1827. /// </param>
  1828. /// <returns type="jQuery" />
  1829. var ret = [], insert = jQuery( selector );
  1830. for ( var i = 0, l = insert.length; i < l; i++ ) {
  1831. var elems = (i > 0 ? this.clone(true) : this).get();
  1832. jQuery.fn[ "after" ].apply( jQuery(insert[i]), elems );
  1833. ret = ret.concat( elems );
  1834. }
  1835. return this.pushStack( ret, "insertAfter", selector );
  1836. };
  1837. jQuery.fn.replaceAll = function( selector ) {
  1838. /// <summary>
  1839. /// 用匹配的元素替换掉所有 (selector选择器)匹配到的元素。
  1840. /// jQuery 1.3.2 会返回所有已插入的元素。
  1841. /// </summary>
  1842. /// <param name="selector" type="Selector">用于查找所要被替换的元素的选择器/param>
  1843. /// <returns type="jQuery" />
  1844. var ret = [], insert = jQuery( selector );
  1845. for ( var i = 0, l = insert.length; i < l; i++ ) {
  1846. var elems = (i > 0 ? this.clone(true) : this).get();
  1847. jQuery.fn[ "replaceWith" ].apply( jQuery(insert[i]), elems );
  1848. ret = ret.concat( elems );
  1849. }
  1850. return this.pushStack( ret, "replaceAll", selector );
  1851. };
  1852. // [vsdoc] The following section has been denormalized from original sources for IntelliSense.
  1853. // jQuery.each({
  1854. //  removeAttr: function( name ) {
  1855. //  jQuery.attr( this, name, "" );
  1856. //  if (this.nodeType == 1)
  1857. //  this.removeAttribute( name );
  1858. //  },
  1859. //
  1860. //  addClass: function( classNames ) {
  1861. //  jQuery.className.add( this, classNames );
  1862. //  },
  1863. //
  1864. //  removeClass: function( classNames ) {
  1865. //  jQuery.className.remove( this, classNames );
  1866. //  },
  1867. //
  1868. //  toggleClass: function( classNames, state ) {
  1869. //  if( typeof state !== "boolean" )
  1870. //  state = !jQuery.className.has( this, classNames );
  1871. //  jQuery.className[ state ? "add" : "remove" ]( this, classNames );
  1872. //  },
  1873. //
  1874. //  remove: function( selector ) {
  1875. //  if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
  1876. //  // Prevent memory leaks
  1877. //  jQuery( "*", this ).add([this]).each(function(){
  1878. //  jQuery.event.remove(this);
  1879. //  jQuery.removeData(this);
  1880. //  });
  1881. //  if (this.parentNode)
  1882. //  this.parentNode.removeChild( this );
  1883. //  }
  1884. //  },
  1885. //
  1886. //  empty: function() {
  1887. //  // Remove element nodes and prevent memory leaks
  1888. //  jQuery( ">*", this ).remove();
  1889. //
  1890. //  // Remove any remaining nodes
  1891. //  while ( this.firstChild )
  1892. //  this.removeChild( this.firstChild );
  1893. //  }
  1894. // }, function(name, fn){
  1895. //  jQuery.fn[ name ] = function(){
  1896. //  return this.each( fn, arguments );
  1897. //  };
  1898. // });
  1899. jQuery.fn.removeAttr = function(){
  1900. /// <summary>
  1901. /// 从每一个匹配的元素中删除一个属性
  1902. /// Part of DOM/Attributes
  1903. /// </summary>
  1904. /// <param name="key" type="String">
  1905. /// 要删除的属性名
  1906. /// </param>
  1907. /// <returns type="jQuery" />
  1908. return this.each( function( name ) {
  1909. jQuery.attr( this, name, "" );
  1910. if (this.nodeType == 1)
  1911. this.removeAttribute( name );
  1912. }, arguments );
  1913. };
  1914. jQuery.fn.addClass = function(clsNames){
  1915. /// <summary>
  1916. /// 为每个匹配的元素添加指定的类名。
  1917. /// Part of DOM/Attributes
  1918. /// </summary>
  1919. /// <param name="clsNames" type="String">
  1920. /// 一个或多个要添加到元素中的CSS类名,请用空格分开。也支持多个参数,每个参数一个类名。
  1921. /// </param>
  1922. /// <returns type="jQuery" />
  1923. return this.each( function( classNames ) {
  1924. jQuery.className.add( this, classNames );
  1925. }, arguments );
  1926. };
  1927. jQuery.fn.removeClass = function(cssClasses){
  1928. /// <summary>
  1929. /// 从所有匹配的元素中删除全部或者指定的类。
  1930. /// Part of DOM/Attributes
  1931. /// </summary>
  1932. /// <param name="cssClasses" type="String" optional="true">
  1933. /// (可选) 一个或多个要删除的CSS类名,请用空格分开。也支持多个参数,每个参数一个类名。
  1934. /// </param>
  1935. /// <returns type="jQuery" />
  1936. return this.each( function( classNames ) {
  1937. jQuery.className.remove( this, classNames );
  1938. }, arguments );
  1939. };
  1940. jQuery.fn.toggleClass = function(cssClass){
  1941. /// <summary>
  1942. /// 如果存在(不存在)就删除(添加)一个类。
  1943. /// Part of DOM/Attributes
  1944. /// </summary>
  1945. /// <param name="cssClass" type="String">
  1946. /// CSS类名
  1947. /// </param>
  1948. /// <returns type="jQuery" />
  1949. return this.each( function( classNames, state ) {
  1950. if( typeof state !== "boolean" )
  1951. state = !jQuery.className.has( this, classNames );
  1952. jQuery.className[ state ? "add" : "remove" ]( this, classNames );
  1953. }, arguments );
  1954. };
  1955. jQuery.fn.remove = function(){
  1956. /// <summary>
  1957. /// 从DOM中删除所有匹配的元素。
  1958. /// 这个方法不会把匹配的元素从jQuery对象中删除,
  1959. /// 因而可以在将来再使用这些匹配的元素。
  1960. /// Part of DOM/Manipulation
  1961. /// </summary>
  1962. /// <param name="expr" type="String" optional="true">
  1963. ///  (可选) 用于筛选元素的jQuery表达式
  1964. /// </param>
  1965. /// <returns type="jQuery" />
  1966. return this.each( function( selector ) {
  1967. if ( !selector || jQuery.filter( selector, [ this ] ).length ) {
  1968. // Prevent memory leaks
  1969. jQuery( "*", this ).add([this]).each(function(){
  1970. jQuery.event.remove(this);
  1971. jQuery.removeData(this);
  1972. });
  1973. if (this.parentNode)
  1974. this.parentNode.removeChild( this );
  1975. }
  1976. }, arguments );
  1977. };
  1978. jQuery.fn.empty = function(){
  1979. /// <summary>
  1980. /// 删除匹配的元素集合中所有的子节点。
  1981. /// Part of DOM/Manipulation
  1982. /// </summary>
  1983. /// <returns type="jQuery" />
  1984. return this.each( function() {
  1985. // Remove element nodes and prevent memory leaks
  1986. jQuery(this).children().remove();
  1987. // Remove any remaining nodes
  1988. while ( this.firstChild )
  1989. this.removeChild( this.firstChild );
  1990. }, arguments );
  1991. };
  1992. // Helper function used by the dimensions and offset modules
  1993. function num(elem, prop) {
  1994. return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
  1995. }
  1996. var expando = "jQuery" + now(), uuid = 0, windowData = {};
  1997. jQuery.extend({
  1998. cache: {},
  1999. data: function( elem, name, data ) {
  2000. elem = elem == window ?
  2001. windowData :
  2002. elem;
  2003. var id = elem[ expando ];
  2004. // Compute a unique ID for the element
  2005. if ( !id )
  2006. id = elem[ expando ] = ++uuid;
  2007. // Only generate the data cache if we're
  2008. // trying to access or manipulate it
  2009. if ( name && !jQuery.cache[ id ] )
  2010. jQuery.cache[ id ] = {};
  2011. // Prevent overriding the named cache with undefined values
  2012. if ( data !== undefined )
  2013. jQuery.cache[ id ][ name ] = data;
  2014. // Return the named cache data, or the ID for the element
  2015. return name ?
  2016. jQuery.cache[ id ][ name ] :
  2017. id;
  2018. },
  2019. removeData: function( elem, name ) {
  2020. elem = elem == window ?
  2021. windowData :
  2022. elem;
  2023. var id = elem[ expando ];
  2024. // If we want to remove a specific section of the element's data
  2025. if ( name ) {
  2026. if ( jQuery.cache[ id ] ) {
  2027. // Remove the section of cache data
  2028. delete jQuery.cache[ id ][ name ];
  2029. // If we've removed all the data, remove the element's cache
  2030. name = "";
  2031. for ( name in jQuery.cache[ id ] )
  2032. break;
  2033. if ( !name )
  2034. jQuery.removeData( elem );
  2035. }
  2036. // Otherwise, we want to remove all of the element's data
  2037. } else {
  2038. // Clean up the element expando
  2039. try {
  2040. delete elem[ expando ];
  2041. } catch(e){
  2042. // IE has trouble directly removing the expando
  2043. // but it's ok with using removeAttribute
  2044. if ( elem.removeAttribute )
  2045. elem.removeAttribute( expando );
  2046. }
  2047. // Completely remove the data cache
  2048. delete jQuery.cache[ id ];
  2049. }
  2050. },
  2051. queue: function( elem, type, data ) {
  2052. if ( elem ){
  2053. type = (type || "fx") + "queue";
  2054. var q = jQuery.data( elem, type );
  2055. if ( !q || jQuery.isArray(data) )
  2056. q = jQuery.data( elem, type, jQuery.makeArray(data) );
  2057. else if( data )
  2058. q.push( data );
  2059. }
  2060. return q;
  2061. },
  2062. dequeue: function( elem, type ){
  2063. var queue = jQuery.queue( elem, type ),
  2064. fn = queue.shift();
  2065. if( !type || type === "fx" )
  2066. fn = queue[0];
  2067. if( fn !== undefined )
  2068. fn.call(elem);
  2069. }
  2070. });
  2071. jQuery.fn.extend({
  2072. data: function( key, value ){
  2073. var parts = key.split(".");
  2074. parts[1] = parts[1] ? "." + parts[1] : "";
  2075. if ( value === undefined ) {
  2076. var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
  2077. if ( data === undefined && this.length )
  2078. data = jQuery.data( this[0], key );
  2079. return data === undefined && parts[1] ?
  2080. this.data( parts[0] ) :
  2081. data;
  2082. } else
  2083. return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
  2084. jQuery.data( this, key, value );
  2085. });
  2086. },
  2087. removeData: function( key ){
  2088. return this.each(function(){
  2089. jQuery.removeData( this, key );
  2090. });
  2091. },
  2092. queue: function(type, data){
  2093. /// <summary>
  2094. /// 1: queue() - 返回指向第一个匹配元素的队列(将是一个函数数组)
  2095. /// 2: queue(callback) - 在匹配的元素的动画队列中添加一个函数
  2096. /// 3: queue(queue) - 将匹配元素的动画队列用新的一个队列来代替(函数数组).
  2097. /// </summary>
  2098. /// <param name="type" type="Function">要添加进队列的函数</param>
  2099. /// <returns type="jQuery" />
  2100. if ( typeof type !== "string" ) {
  2101. data = type;
  2102. type = "fx";
  2103. }
  2104. if ( data === undefined )
  2105. return jQuery.queue( this[0], type );
  2106. return this.each(function(){
  2107. var queue = jQuery.queue( this, type, data );
  2108.  if( type == "fx" && queue.length == 1 )
  2109. queue[0].call(this);
  2110. });
  2111. },
  2112. dequeue: function(type){
  2113. /// <summary>
  2114. /// Removes a queued function from the front of the queue and executes it.
  2115. /// </summary>
  2116. /// <param name="type" type="String" optional="true">The type of queue to access.</param>
  2117. /// <returns type="jQuery" />
  2118. return this.each(function(){
  2119. jQuery.dequeue( this, type );
  2120. });
  2121. }
  2122. });/*!
  2123.  * Sizzle CSS Selector Engine - v0.9.3
  2124.  *  Copyright 2009, The Dojo Foundation
  2125.  *  Released under the MIT, BSD, and GPL Licenses.
  2126.  *  More information: http://sizzlejs.com/
  2127.  */
  2128. (function(){
  2129. var chunker = /((?:((?:([^()]+)|[^()]+)+)|[(?:[[^[]]*]|['"][^'"]*['"]|[^[]'"]+)+]|\.|[^ >+~,([\]+)+|[>+~])(s*,s*)?/g,
  2130. done = 0,
  2131. toString = Object.prototype.toString;
  2132. var Sizzle = function(selector, context, results, seed) {
  2133. results = results || [];
  2134. context = context || document;
  2135. if ( context.nodeType !== 1 && context.nodeType !== 9 )
  2136. return [];
  2137. if ( !selector || typeof selector !== "string" ) {
  2138. return results;
  2139. }
  2140. var parts = [], m, set, checkSet, check, mode, extra, prune = true;
  2141. // Reset the position of the chunker regexp (start from head)
  2142. chunker.lastIndex = 0;
  2143. while ( (m = chunker.exec(selector)) !== null ) {
  2144. parts.push( m[1] );
  2145. if ( m[2] ) {
  2146. extra = RegExp.rightContext;
  2147. break;
  2148. }
  2149. }
  2150. if ( parts.length > 1 && origPOS.exec( selector ) ) {
  2151. if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
  2152. set = posProcess( parts[0] + parts[1], context );
  2153. } else {
  2154. set = Expr.relative[ parts[0] ] ?
  2155. [ context ] :
  2156. Sizzle( parts.shift(), context );
  2157. while ( parts.length ) {
  2158. selector = parts.shift();
  2159. if ( Expr.relative[ selector ] )
  2160. selector += parts.shift();
  2161. set = posProcess( selector, set );
  2162. }
  2163. }
  2164. } else {
  2165. var ret = seed ?
  2166. { expr: parts.pop(), set: makeArray(seed) } :
  2167. Sizzle.find( parts.pop(), parts.length === 1 && context.parentNode ? context.parentNode : context, isXML(context) );
  2168. set = Sizzle.filter( ret.expr, ret.set );
  2169. if ( parts.length > 0 ) {
  2170. checkSet = makeArray(set);
  2171. } else {
  2172. prune = false;
  2173. }
  2174. while ( parts.length ) {
  2175. var cur = parts.pop(), pop = cur;
  2176. if ( !Expr.relative[ cur ] ) {
  2177. cur = "";
  2178. } else {
  2179. pop = parts.pop();
  2180. }
  2181. if ( pop == null ) {
  2182. pop = context;
  2183. }
  2184. Expr.relative[ cur ]( checkSet, pop, isXML(context) );
  2185. }
  2186. }
  2187. if ( !checkSet ) {
  2188. checkSet = set;
  2189. }
  2190. if ( !checkSet ) {
  2191. throw "Syntax error, unrecognized expression: " + (cur || selector);
  2192. }
  2193. if ( toString.call(checkSet) === "[object Array]" ) {
  2194. if ( !prune ) {
  2195. results.push.apply( results, checkSet );
  2196. } else if ( context.nodeType === 1 ) {
  2197. for ( var i = 0; checkSet[i] != null; i++ ) {
  2198. if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
  2199. results.push( set[i] );
  2200. }
  2201. }
  2202. } else {
  2203. for ( var i = 0; checkSet[i] != null; i++ ) {
  2204. if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
  2205. results.push( set[i] );
  2206. }
  2207. }
  2208. }
  2209. } else {
  2210. makeArray( checkSet, results );
  2211. }
  2212. if ( extra ) {
  2213. Sizzle( extra, context, results, seed );
  2214. if ( sortOrder ) {
  2215. hasDuplicate = false;
  2216. results.sort(sortOrder);
  2217. if ( hasDuplicate ) {
  2218. for ( var i = 1; i < results.length; i++ ) {
  2219. if ( results[i] === results[i-1] ) {
  2220. results.splice(i--, 1);
  2221. }
  2222. }
  2223. }
  2224. }
  2225. }
  2226. return results;
  2227. };
  2228. Sizzle.matches = function(expr, set){
  2229. return Sizzle(expr, null, null, set);
  2230. };
  2231. Sizzle.find = function(expr, context, isXML){
  2232. var set, match;
  2233. if ( !expr ) {
  2234. return [];
  2235. }
  2236. for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
  2237. var type = Expr.order[i], match;
  2238. if ( (match = Expr.match[ type ].exec( expr )) ) {
  2239. var left = RegExp.leftContext;
  2240. if ( left.substr( left.length - 1 ) !== "\" ) {
  2241. match[1] = (match[1] || "").replace(/\/g, "");
  2242. set = Expr.find[ type ]( match, context, isXML );
  2243. if ( set != null ) {
  2244. expr = expr.replace( Expr.match[ type ], "" );
  2245. break;
  2246. }
  2247. }
  2248. }
  2249. }
  2250. if ( !set ) {
  2251. set = context.getElementsByTagName("*");
  2252. }
  2253. return {set: set, expr: expr};
  2254. };
  2255. Sizzle.filter = function(expr, set, inplace, not){
  2256. var old = expr, result = [], curLoop = set, match, anyFound,
  2257. isXMLFilter = set && set[0] && isXML(set[0]);
  2258. while ( expr && set.length ) {
  2259. for ( var type in Expr.filter ) {
  2260. if ( (match = Expr.match[ type ].exec( expr )) != null ) {
  2261. var filter = Expr.filter[ type ], found, item;
  2262. anyFound = false;
  2263. if ( curLoop == result ) {
  2264. result = [];
  2265. }
  2266. if ( Expr.preFilter[ type ] ) {
  2267. match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
  2268. if ( !match ) {
  2269. anyFound = found = true;
  2270. } else if ( match === true ) {
  2271. continue;
  2272. }
  2273. }
  2274. if ( match ) {
  2275. for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
  2276. if ( item ) {
  2277. found = filter( item, match, i, curLoop );
  2278. var pass = not ^ !!found;
  2279. if ( inplace && found != null ) {
  2280. if ( pass ) {
  2281. anyFound = true;
  2282. } else {
  2283. curLoop[i] = false;
  2284. }
  2285. } else if ( pass ) {
  2286. result.push( item );
  2287. anyFound = true;
  2288. }
  2289. }
  2290. }
  2291. }
  2292. if ( found !== undefined ) {
  2293. if ( !inplace ) {
  2294. curLoop = result;
  2295. }
  2296. expr = expr.replace( Expr.match[ type ], "" );
  2297. if ( !anyFound ) {
  2298. return [];
  2299. }
  2300. break;
  2301. }
  2302. }
  2303. }
  2304. // Improper expression
  2305. if ( expr == old ) {
  2306. if ( anyFound == null ) {
  2307. throw "Syntax error, unrecognized expression: " + expr;
  2308. } else {
  2309. break;
  2310. }
  2311. }
  2312. old = expr;
  2313. }
  2314. return curLoop;
  2315. };
  2316. var Expr = Sizzle.selectors = {
  2317. order: [ "ID", "NAME", "TAG" ],
  2318. match: {
  2319. ID: /#((?:[wu00c0-uFFFF_-]|\.)+)/,
  2320. CLASS: /.((?:[wu00c0-uFFFF_-]|\.)+)/,
  2321. NAME: /[name=['"]*((?:[wu00c0-uFFFF_-]|\.)+)['"]*]/,
  2322. ATTR: /[s*((?:[wu00c0-uFFFF_-]|\.)+)s*(?:(S?=)s*(['"]*)(.*?)3|)s*]/,
  2323. TAG: /^((?:[wu00c0-uFFFF*_-]|\.)+)/,
  2324. CHILD: /:(only|nth|last|first)-child(?:((even|odd|[dn+-]*)))?/,
  2325. POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:((d*)))?(?=[^-]|$)/,
  2326. PSEUDO: /:((?:[wu00c0-uFFFF_-]|\.)+)(?:((['"]*)((?:([^)]+)|[^2()]*)+)2))?/
  2327. },
  2328. attrMap: {
  2329. "class": "className",
  2330. "for": "htmlFor"
  2331. },
  2332. attrHandle: {
  2333. href: function(elem){
  2334. return elem.getAttribute("href");
  2335. }
  2336. },
  2337. relative: {
  2338. "+": function(checkSet, part, isXML){
  2339. var isPartStr = typeof part === "string",
  2340. isTag = isPartStr && !/W/.test(part),
  2341. isPartStrNotTag = isPartStr && !isTag;
  2342. if ( isTag && !isXML ) {
  2343. part = part.toUpperCase();
  2344. }
  2345. for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
  2346. if ( (elem = checkSet[i]) ) {
  2347. while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
  2348. checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
  2349. elem || false :
  2350. elem === part;
  2351. }
  2352. }
  2353. if ( isPartStrNotTag ) {
  2354. Sizzle.filter( part, checkSet, true );
  2355. }
  2356. },
  2357. ">": function(checkSet, part, isXML){
  2358. var isPartStr = typeof part === "string";
  2359. if ( isPartStr && !/W/.test(part) ) {
  2360. part = isXML ? part : part.toUpperCase();
  2361. for ( var i = 0, l = checkSet.length; i < l; i++ ) {
  2362. var elem = checkSet[i];
  2363. if ( elem ) {
  2364. var parent = elem.parentNode;
  2365. checkSet[i] = parent.nodeName === part ? parent : false;
  2366. }
  2367. }
  2368. } else {
  2369. for ( var i = 0, l = checkSet.length; i < l; i++ ) {
  2370. var elem = checkSet[i];
  2371. if ( elem ) {
  2372. checkSet[i] = isPartStr ?
  2373. elem.parentNode :
  2374. elem.parentNode === part;
  2375. }
  2376. }
  2377. if ( isPartStr ) {
  2378. Sizzle.filter( part, checkSet, true );
  2379. }
  2380. }
  2381. },
  2382. "": function(checkSet, part, isXML){
  2383. var doneName = done++, checkFn = dirCheck;
  2384. if ( !part.match(/W/) ) {
  2385. var nodeCheck = part = isXML ? part : part.toUpperCase();
  2386. checkFn = dirNodeCheck;
  2387. }
  2388. checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
  2389. },
  2390. "~": function(checkSet, part, isXML){
  2391. var doneName = done++, checkFn = dirCheck;
  2392. if ( typeof part === "string" && !part.match(/W/) ) {
  2393. var nodeCheck = part = isXML ? part : part.toUpperCase();
  2394. checkFn = dirNodeCheck;
  2395. }
  2396. checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
  2397. }
  2398. },
  2399. find: {
  2400. ID: function(match, context, isXML){
  2401. if ( typeof context.getElementById !== "undefined" && !isXML ) {
  2402. var m = context.getElementById(match[1]);
  2403. return m ? [m] : [];
  2404. }
  2405. },
  2406. NAME: function(match, context, isXML){
  2407. if ( typeof context.getElementsByName !== "undefined" ) {
  2408. var ret = [], results = context.getElementsByName(match[1]);
  2409. for ( var i = 0, l = results.length; i < l; i++ ) {
  2410. if ( results[i].getAttribute("name") === match[1] ) {
  2411. ret.push( results[i] );
  2412. }
  2413. }
  2414. return ret.length === 0 ? null : ret;
  2415. }
  2416. },
  2417. TAG: function(match, context){
  2418. return context.getElementsByTagName(match[1]);
  2419. }
  2420. },
  2421. preFilter: {
  2422. CLASS: function(match, curLoop, inplace, result, not, isXML){
  2423. match = " " + match[1].replace(/\/g, "") + " ";
  2424. if ( isXML ) {
  2425. return match;
  2426. }
  2427. for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
  2428. if ( elem ) {
  2429. if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
  2430. if ( !inplace )
  2431. result.push( elem );
  2432. } else if ( inplace ) {
  2433. curLoop[i] = false;
  2434. }
  2435. }
  2436. }
  2437. return false;
  2438. },
  2439. ID: function(match){
  2440. return match[1].replace(/\/g, "");
  2441. },
  2442. TAG: function(match, curLoop){
  2443. for ( var i = 0; curLoop[i] === false; i++ ){}
  2444. return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
  2445. },
  2446. CHILD: function(match){
  2447. if ( match[1] == "nth" ) {
  2448. // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
  2449. var test = /(-?)(d*)n((?:+|-)?d*)/.exec(
  2450. match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
  2451. !/D/.test( match[2] ) && "0n+" + match[2] || match[2]);
  2452. // calculate the numbers (first)n+(last) including if they are negative
  2453. match[2] = (test[1] + (test[2] || 1)) - 0;
  2454. match[3] = test[3] - 0;
  2455. }
  2456. // TODO: Move to normal caching system
  2457. match[0] = done++;
  2458. return match;
  2459. },
  2460. ATTR: function(match, curLoop, inplace, result, not, isXML){
  2461. var name = match[1].replace(/\/g, "");
  2462. if ( !isXML && Expr.attrMap[name] ) {
  2463. match[1] = Expr.attrMap[name];
  2464. }
  2465. if ( match[2] === "~=" ) {
  2466. match[4] = " " + match[4] + " ";
  2467. }
  2468. return match;
  2469. },
  2470. PSEUDO: function(match, curLoop, inplace, result, not){
  2471. if ( match[1] === "not" ) {
  2472. // If we're dealing with a complex expression, or a simple one
  2473. if ( match[3].match(chunker).length > 1 || /^w/.test(match[3]) ) {
  2474. match[3] = Sizzle(match[3], null, null, curLoop);
  2475. } else {
  2476. var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
  2477. if ( !inplace ) {
  2478. result.push.apply( result, ret );
  2479. }
  2480. return false;
  2481. }
  2482. } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
  2483. return true;
  2484. }
  2485. return match;
  2486. },
  2487. POS: function(match){
  2488. match.unshift( true );
  2489. return match;
  2490. }
  2491. },
  2492. filters: {
  2493. enabled: function(elem){
  2494. return elem.disabled === false && elem.type !== "hidden";
  2495. },
  2496. disabled: function(elem){
  2497. return elem.disabled === true;
  2498. },
  2499. checked: function(elem){
  2500. return elem.checked === true;
  2501. },
  2502. selected: function(elem){
  2503. // Accessing this property makes selected-by-default
  2504. // options in Safari work properly
  2505. elem.parentNode.selectedIndex;
  2506. return elem.selected === true;
  2507. },
  2508. parent: function(elem){
  2509. return !!elem.firstChild;
  2510. },
  2511. empty: function(elem){
  2512. return !elem.firstChild;
  2513. },
  2514. has: function(elem, i, match){
  2515. return !!Sizzle( match[3], elem ).length;
  2516. },
  2517. header: function(elem){
  2518. return /hd/i.test( elem.nodeName );
  2519. },
  2520. text: function(elem){
  2521. return "text" === elem.type;
  2522. },
  2523. radio: function(elem){
  2524. return "radio" === elem.type;
  2525. },
  2526. checkbox: function(elem){
  2527. return "checkbox" === elem.type;
  2528. },
  2529. file: function(elem){
  2530. return "file" === elem.type;
  2531. },
  2532. password: function(elem){
  2533. return "password" === elem.type;
  2534. },
  2535. submit: function(elem){
  2536. return "submit" === elem.type;
  2537. },
  2538. image: function(elem){
  2539. return "image" === elem.type;
  2540. },
  2541. reset: function(elem){
  2542. return "reset" === elem.type;
  2543. },
  2544. button: function(elem){
  2545. return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
  2546. },
  2547. input: function(elem){
  2548. return /input|select|textarea|button/i.test(elem.nodeName);
  2549. }
  2550. },
  2551. setFilters: {
  2552. first: function(elem, i){
  2553. return i === 0;
  2554. },
  2555. last: function(elem, i, match, array){
  2556. return i === array.length - 1;
  2557. },
  2558. even: function(elem, i){
  2559. return i % 2 === 0;
  2560. },
  2561. odd: function(elem, i){
  2562. return i % 2 === 1;
  2563. },
  2564. lt: function(elem, i, match){
  2565. return i < match[3] - 0;
  2566. },
  2567. gt: function(elem, i, match){
  2568. return i > match[3] - 0;
  2569. },
  2570. nth: function(elem, i, match){
  2571. return match[3] - 0 == i;
  2572. },
  2573. eq: function(elem, i, match){
  2574. return match[3] - 0 == i;
  2575. }
  2576. },
  2577. filter: {
  2578. PSEUDO: function(elem, match, i, array){
  2579. var name = match[1], filter = Expr.filters[ name ];
  2580. if ( filter ) {
  2581. return filter( elem, i, match, array );
  2582. } else if ( name === "contains" ) {
  2583. return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
  2584. } else if ( name === "not" ) {
  2585. var not = match[3];
  2586. for ( var i = 0, l = not.length; i < l; i++ ) {
  2587. if ( not[i] === elem ) {
  2588. return false;
  2589. }
  2590. }
  2591. return true;
  2592. }
  2593. },
  2594. CHILD: function(elem, match){
  2595. var type = match[1], node = elem;
  2596. switch (type) {
  2597. case 'only':
  2598. case 'first':
  2599. while (node = node.previousSibling)  {
  2600. if ( node.nodeType === 1 ) return false;
  2601. }
  2602. if ( type == 'first') return true;
  2603. node = elem;
  2604. case 'last':
  2605. while (node = node.nextSibling)  {
  2606. if ( node.nodeType === 1 ) return false;
  2607. }
  2608. return true;
  2609. case 'nth':
  2610. var first = match[2], last = match[3];
  2611. if ( first == 1 && last == 0 ) {
  2612. return true;
  2613. }
  2614. var doneName = match[0],
  2615. parent = elem.parentNode;
  2616. if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
  2617. var count = 0;
  2618. for ( node = parent.firstChild; node; node = node.nextSibling ) {
  2619. if ( node.nodeType === 1 ) {
  2620. node.nodeIndex = ++count;
  2621. }
  2622. }
  2623. parent.sizcache = doneName;
  2624. }
  2625. var diff = elem.nodeIndex - last;
  2626. if ( first == 0 ) {
  2627. return diff == 0;
  2628. } else {
  2629. return ( diff % first == 0 && diff / first >= 0 );
  2630. }
  2631. }
  2632. },
  2633. ID: function(elem, match){
  2634. return elem.nodeType === 1 && elem.getAttribute("id") === match;
  2635. },
  2636. TAG: function(elem, match){
  2637. return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
  2638. },
  2639. CLASS: function(elem, match){
  2640. return (" " + (elem.className || elem.getAttribute("class")) + " ")
  2641. .indexOf( match ) > -1;
  2642. },
  2643. ATTR: function(elem, match){
  2644. var name = match[1],
  2645. result = Expr.attrHandle[ name ] ?
  2646. Expr.attrHandle[ name ]( elem ) :
  2647. elem[ name ] != null ?
  2648. elem[ name ] :
  2649. elem.getAttribute( name ),
  2650. value = result + "",
  2651. type = match[2],
  2652. check = match[4];
  2653. return result == null ?
  2654. type === "!=" :