diff --git a/src/main/webapp/js/jquery-1.12.4.js b/src/main/webapp/js/jquery-1.12.4.js index cbfd965..7c7eab6 100644 --- a/src/main/webapp/js/jquery-1.12.4.js +++ b/src/main/webapp/js/jquery-1.12.4.js @@ -13,872 +13,7 @@ * jQuery的立即执行函数表达式(IIFE),用于创建一个封闭的作用域,避免全局变量污染。 * 它接受两个参数:global(全局对象,通常为window)和factory(一个函数,用于定义jQuery)。 */ -(function( global, factory ) { - - // 如果在CommonJS环境中(如Node.js),并且module.exports存在 - if ( typeof module === "object" && typeof module.exports === "object" ) { - - // 如果全局对象有document属性,则直接导出jQuery - // 否则,导出一个函数,该函数在被调用时会检查是否存在document - module.exports = global.document ? - factory( global, true ) : - function( w ) { - // 如果没有document,则抛出错误 - if ( !w.document ) { - throw new Error( "jQuery需要一个包含document的window对象" ); - } - // 否则,调用factory函数创建jQuery - return factory( w ); - }; - } else { - // 在非CommonJS环境中,直接调用factory函数 - factory( global ); - } - -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - - // 用于存储已删除的ID的数组 - var deletedIds = []; - - // 获取全局的document对象 - var document = window.document; - - // 从deletedIds数组借用一些数组方法,用于后续操作 - var slice = deletedIds.slice; - var concat = deletedIds.concat; - var push = deletedIds.push; - var indexOf = deletedIds.indexOf; - - // 一个空对象,用于存储类名到类型的映射 - var class2type = {}; - - // 获取class2type对象的toString方法 - var toString = class2type.toString; - - // 获取class2type对象的hasOwnProperty方法 - var hasOwn = class2type.hasOwnProperty; - - // 一个空对象,用于存储浏览器支持的特性 - var support = {}; - - // jQuery的版本号 - var version = "1.12.4"; - - // 定义jQuery对象,它实际上是init构造函数的增强版 - var jQuery = function( selector, context ) { - // 如果直接调用jQuery而没有new,这里会返回一个新的jQuery.fn.init实例 - return new jQuery.fn.init( selector, context ); - }; - - // 匹配并去除字符串开头和结尾的空白字符(包括BOM和NBSP) - var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; - - // 匹配以"-ms-"开头的字符串 - var rmsPrefix = /^-ms-/; - - // 匹配并替换字符串中的"-"后跟一个字母或数字的字符 - var rdashAlpha = /-([\da-z])/gi; - - // 用于将"-"后跟字母的字符串转换为驼峰命名法的回调函数 - var fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - - // jQuery的原型对象,包含所有实例方法 - jQuery.fn = jQuery.prototype = { - - // 当前jQuery的版本号 - jquery: version, - - // 构造函数指向jQuery本身 - constructor: jQuery, - - // 初始选择器字符串 - selector: "", - - // jQuery对象的默认长度为0 - length: 0, - - // 将jQuery对象转换为一个真正的数组 - toArray: function() { - return slice.call( this ); - }, - - // 获取jQuery对象中的第N个元素,或者获取所有元素组成的数组 - get: function( num ) { - return num != null ? - - // 返回指定位置的元素 - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // 返回所有元素组成的数组 - slice.call( this ); - }, - - // 将一个元素数组推入到当前jQuery对象的栈中,并返回新的jQuery对象 - pushStack: function( elems ) { - - // 创建一个新的jQuery对象 - var ret = jQuery.merge( this.constructor(), elems ); - - // 将旧的对象引用添加到新对象的prevObject属性上 - ret.prevObject = this; - // 保持上下文的一致性 - ret.context = this.context; - - // 返回新的jQuery对象 - return ret; - }, - - // 对jQuery对象中的每个元素执行一次提供的回调函数 - each: function( callback ) { - return jQuery.each( this, callback ); - }, - - // 将jQuery对象中的每个元素通过提供的回调函数映射到一个新数组中,并返回一个新的jQuery对象 - map: function( callback ) { - return this.pushStack( jQuery.map( this, function( elem, i ) { - return callback.call( elem, i, elem ); - }) ); - }, - - // 返回一个从当前位置开始,包含指定数量元素的新jQuery对象(如果参数是负数,则从末尾开始计数) - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - // 获取jQuery对象中的第一个元素 - first: function() { - return this.eq( 0 ); - }, - - // 获取jQuery对象中的最后一个元素 - last: function() { - return this.eq( -1 ); - }, - - // 获取jQuery对象中指定位置的元素(如果索引是负数,则从末尾开始计数) - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); - }, - - // 结束当前操作,返回到上一个jQuery对象(如果有的话) - end: function() { - return this.prevObject || this.constructor(); - }, - - // 以下方法是从数组对象中借用来的,用于内部使用 - push: push, - sort: deletedIds.sort, - splice: deletedIds.splice - }; - - // jQuery.extend方法用于扩展jQuery对象本身或其原型对象 - jQuery.extend = jQuery.fn.extend = function() { - var src, copyIsArray, copy, name, options, clone, - target = arguments[ 0 ] || {}, - i = 1, - length = arguments.length, - deep = false; - - // 处理深度复制的情况 - if ( typeof target === "boolean" ) { - deep = target; - - // 跳过布尔值和目标对象 - target = arguments[ i ] || {}; - i++; - } - - // 如果目标不是对象或函数,则将其转换为对象 - if ( typeof target !== "object" && !jQuery.isFunction( target ) ) { - target = {}; - } - - // 如果只有一个参数,则扩展jQuery本身 - if ( i === length ) { - target = this; - i--; - } - - // 遍历每一个要扩展的对象 - for ( ; i < length; i++ ) { - - // 只处理非null/undefined的值 - if ( ( options = arguments[ i ] ) != null ) { - - // 扩展基础对象 - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // 防止无限循环 - if ( target === copy ) { - continue; - } - // 深度复制的逻辑(略) - - // Recurse if we're merging plain objects or arrays - // 定义一个函数,用于扩展对象或合并对象 -// deep 参数指示是否进行深度拷贝 -// copy 是要合并到第一个对象中的对象或数组 -// target 是被扩展的对象 - var someFunction = function( deep, copy, target ) { - // 检查是否进行深度拷贝,且copy是一个纯对象或数组 - if ( deep && copy && ( jQuery.isPlainObject( copy ) || - ( copyIsArray = jQuery.isArray( copy ) ) ) ) { - - // 如果copy是数组 - if ( copyIsArray ) { - copyIsArray = false; // 重置标志位,因为已经处理过是数组的情况 - clone = src && jQuery.isArray( src ) ? src : []; // 根据src是否为数组来决定clone是src的引用还是新数组 - - } else { - // 如果copy是纯对象 - clone = src && jQuery.isPlainObject( src ) ? src : {}; // 根据src是否为纯对象来决定clone是src的引用还是新对象 - } - - // 从不直接移动原始对象,而是克隆它们 - // 使用jQuery.extend进行合并,可能涉及深度拷贝 - target[ name ] = jQuery.extend( deep, clone, copy ); - - // 如果copy不是undefined,则直接赋值给target[name] - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - -// jQuery的静态方法集合 - jQuery.extend( { - - // 每个jQuery实例在页面上的唯一标识符 - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // 假设没有ready模块时,jQuery已准备好 - isReady: true, - - // 错误处理函数 - error: function( msg ) { - throw new Error( msg ); - }, - - // 空函数,常用于回调占位 - noop: function() {}, - - // 判断对象是否为函数 - isFunction: function( obj ) { - return jQuery.type( obj ) === "function"; - }, - - // 判断对象是否为数组 - isArray: Array.isArray || function( obj ) { - return jQuery.type( obj ) === "array"; - }, - - // 判断对象是否为窗口对象 - isWindow: function( obj ) { - return obj != null && obj == obj.window; - }, - - // 判断对象是否为数字 - isNumeric: function( obj ) { - var realStringObj = obj && obj.toString(); - return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0; - }, - - // 判断对象是否为空对象 - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - // 判断对象是否为纯对象(即直接通过{}或new Object()创建的对象) - isPlainObject: function( obj ) { - var key; - if ( !obj || jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - try { - if ( obj.constructor && - !hasOwn.call( obj, "constructor" ) && - !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) { - return false; - } - } catch ( e ) { - return false; - } - if ( !support.ownFirst ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } - } - for ( key in obj ) {} - return key === undefined || hasOwn.call( obj, key ); - }, - - // 获取对象的类型 - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call( obj ) ] || "object" : - typeof obj; - }, - - // 在全局上下文中执行JavaScript代码 - globalEval: function( data ) { - if ( data && jQuery.trim( data ) ) { - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // 将字符串从dashed转换为camelCase - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - // 检查元素是否具有指定的节点名称 - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // 遍历对象或数组 - each: function( obj, callback ) { - var length, i = 0; - if ( isArrayLike( obj ) ) { - length = obj.length; - for ( ; i < length; i++ ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } else { - for ( i in obj ) { - if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { - break; - } - } - } - return obj; - }, - }); - // Support: Android<4.1, IE<9 - // 去除字符串两端的空白字符 - trim: function(text) { - // 如果text为null或undefined,则返回空字符串 - return text == null ? - "" : - // 将text转换为字符串(如果text不是字符串的话),然后使用正则表达式去除两端的空白字符 - (text + "").replace(rtrim, ""); - }, - -// 将类数组对象或可迭代对象转换为真正的数组,results是内部使用参数,用于存储转换结果 - makeArray: function(arr, results) { - var ret = results || []; // 如果没有传入results,则初始化为空数组 - - if (arr != null) { // 如果arr不为null或undefined - // 判断arr是否类似数组 - if (isArrayLike(Object(arr))) { - // 如果是字符串,则将其放入数组中,否则直接使用arr - jQuery.merge(ret, - typeof arr === "string" ? - [arr] : arr - ); - } else { - // 使用push方法将arr添加到ret数组中 - push.call(ret, arr); - } - } - - return ret; // 返回转换后的数组 - }, - -// 判断元素是否在数组中,返回元素的索引,如果不在则返回-1 - inArray: function(elem, arr, i) { - var len; - - if (arr) { // 如果数组不为空 - if (indexOf) { // 如果indexOf方法存在(现代浏览器) - return indexOf.call(arr, elem, i); // 使用indexOf查找元素索引 - } - - len = arr.length; // 获取数组长度 - i = i ? i < 0 ? Math.max(0, len + i) : i : 0; // 处理负数索引 - - // 遍历数组,查找元素 - for (; i < len; i++) { - // 跳过稀疏数组中的空位 - if (i in arr && arr[i] === elem) { - return i; // 找到元素,返回索引 - } - } - } - - return -1; // 未找到元素,返回-1 - }, - -// 合并两个数组,将第二个数组的元素添加到第一个数组中 - merge: function(first, second) { - var len = +second.length, // 获取second数组的长度(转换为数字) - j = 0, - i = first.length; // 获取first数组的长度 - - // 使用while循环将second数组的元素添加到first数组中 - while (j < len) { - first[i++] = second[j++]; - } - - // 支持IE<9,处理类数组对象(如NodeLists)的长度属性可能不是数字的情况 - if (len !== len) { // 如果len转换为数字后与自身不相等(NaN的情况) - while (second[j] !== undefined) { // 继续添加元素,直到second[j]为undefined - first[i++] = second[j++]; - } - } - - first.length = i; // 更新first数组的长度 - - return first; // 返回合并后的数组 - }, - -// 使用回调函数过滤数组,返回满足条件的元素组成的新数组 - grep: function(elems, callback, invert) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; // 根据invert的值确定callback的期望返回值(true或false) - - // 遍历数组,将满足条件的元素添加到matches数组中 - for (; i < length; i++) { - callbackInverse = !callback(elems[i], i); // 调用回调函数,并取反 - if (callbackInverse !== callbackExpect) { // 如果回调函数的返回值与期望不符 - matches.push(elems[i]); // 将元素添加到matches数组中 - } - } - - return matches; // 返回过滤后的数组 - }, - -// 对数组或对象进行映射,返回一个新数组,数组中的每个元素都是回调函数处理后的结果 - map: function(elems, callback, arg) { - var length, value, - i = 0, - ret = []; // 初始化返回数组 - - // 判断elems是否是类数组对象 - if (isArrayLike(elems)) { - length = elems.length; // 获取elems的长度 - // 遍历elems数组 - for (; i < length; i++) { - value = callback(elems[i], i, arg); // 调用回调函数处理元素 - if (value != null) { // 如果回调函数返回值不为null或undefined - ret.push(value); // 将返回值添加到ret数组中 - } - } - } else { - // 如果elems不是类数组对象,则遍历其所有属性 - for (i in elems) { - value = callback(elems[i], i, arg); // 调用回调函数处理元素 - if (value != null) { // 如果回调函数返回值不为null或undefined - ret.push(value); // 将返回值添加到ret数组中 - } - } - } - - // 使用concat方法将ret数组中的嵌套数组展平 - return concat.apply([], ret); - }, - -// 全局GUID计数器,用于生成唯一标识符 - guid: 1, - -// 绑定函数到指定上下文,并可选地预设一些参数 - proxy: function(fn, context) { - var args, proxy, tmp; - - // 如果context是字符串,则假设是要绑定到fn的某个方法上 - if (typeof context === "string") { - tmp = fn[context]; - context = fn; - fn = tmp; - } - - // 检查fn是否为函数,如果不是则返回undefined - if (!jQuery.isFunction(fn)) { - return undefined; - } - - // 保存额外参数 - args = slice.call(arguments, 2); - // 创建代理函数 - proxy = function() { - // 将预设参数和当前调用的参数合并,然后调用原函数 - return fn.apply(context || this, args.concat(slice.call(arguments))); - }; - - // 设置代理函数的guid,以便可以移除事件监听器等 - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; // 返回代理函数 - }, - -// 获取当前时间的毫秒数 - now: function() { - return +(new Date()); // 返回Date对象的时间戳(毫秒数) - }, - -// jQuery.support已不在核心中使用,但其他项目可能会附加属性到它上面,因此需要保留 - support: support - }); - -// 以下代码块由于使用了ES6的Symbol,可能会导致JSHint报错,因此使用注释忽略JSHint的检查 - /* jshint ignore: start */ - if (typeof Symbol === "function") { - jQuery.fn[Symbol.iterator] = deletedIds[Symbol.iterator]; // 为jQuery对象设置Symbol.iterator属性,以便支持迭代 - } - /* jshint ignore: end */ - -// 填充class2type映射表 - jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), - function(i, name) { - class2type["[object " + name + "]"] = name.toLowerCase(); // 将类名字符串映射为小写形式并存储在class2type对象中 - }); - -// 判断一个对象是否类似数组 - function isArrayLike(obj) { - var length = !!obj && "length" in obj && obj.length, // 获取对象的length属性(如果存在的话) - type = jQuery.type(obj); // 获取对象的类型 - - // 如果对象是函数或window对象,则不是类似数组 - if (type === "function" || jQuery.isWindow(obj)) { - return false; - } - - // 返回对象是否为数组或长度大于0且length-1索引存在的对象(处理稀疏数组) - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && (length - 1) in obj; - } - var Sizzle = - /*! - * Sizzle CSS Selector Engine v2.2.1 - * http://sizzlejs.com/ - * - * Copyright jQuery Foundation and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2015-10-17 - */ - (function(window) { - // 省略Sizzle选择器引擎的代码... - }); - - - // 创建一个独特的expando属性名,用于存储数据,结合当前时间戳 - expando = "sizzle" + 1 * new Date(), - -// 获取全局的document对象 - preferredDoc = window.document, - -// 运行方向计数器(可能用于跟踪查询的执行顺序) - dirruns = 0, - -// 完成标志(可能用于跟踪查询是否已完成) - done = 0, - -// 创建缓存对象,用于存储类名、标记和编译器的缓存 - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - -// 排序函数,用于排序,如果两个元素相同,则标记有重复 - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - -// 常量定义 - MAX_NEGATIVE = 1 << 31, - -// 实例方法 - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, // 注意:这里push被重新赋值,下面会解释 - slice = arr.slice, - -// 自定义的indexOf方法,用于查找元素在数组中的位置 - indexOf = function( list, elem ) { - var i = 0, - len = list.length; - for ( ; i < len; i++ ) { - if ( list[i] === elem ) { - return i; - } - } - return -1; - }, - -// 布尔属性字符串,用于快速检查元素是否具有这些属性 - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - -// 正则表达式定义,用于匹配不同类型的选择器 -// ...(省略了具体的正则表达式定义,因为它们很长且专注于选择器解析) - -// matchExpr对象,用于快速匹配不同类型的选择器 - matchExpr = { - // ...(省略了具体的匹配规则) - }, - -// 用于检查元素类型的正则表达式 - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - -// 用于检测原生方法的正则表达式 - rnative = /^[^{]+\{\s*\[native \w/, - -// 快速表达式匹配,用于解析ID、标签或类选择器 - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - -// 用于匹配兄弟选择器的正则表达式 - rsibling = /[+~]/, - rescape = /'|\\/g, - -// CSS转义字符的正则表达式和函数 - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - // ...(省略了具体的转义逻辑) - }, - -// 卸载处理器,用于在页面卸载时重置文档 - unloadHandler = function() { - setDocument(); - }; - -// 优化push.apply的使用,尝试直接应用NodeList到数组 - try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // 尝试访问最后一个元素的nodeType来检测是否成功 - arr[ preferredDoc.childNodes.length ].nodeType; - } catch ( e ) { - // 如果失败,则使用替代的push方法 - push = { apply: arr.length ? - - // 如果原生slice可用,则使用它 - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // 否则,逐个添加元素到目标数组 - function( target, els ) { - var j = target.length, - i = 0; - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; - } - -// Sizzle函数,是选择器引擎的核心 - function Sizzle( selector, context, results, seed ) { - var m, i, elem, nid, nidselect, match, groups, newSelector, - newContext = context && context.ownerDocument, - nodeType = context ? context.nodeType : 9; // 9代表document节点 - - results = results || []; - - // 如果选择器不是字符串、为空、或者上下文节点类型不正确,则直接返回空结果 - if ( typeof selector !== "string" || !selector || - nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { - - return results; - } - // ...(省略了Sizzle函数的具体实现,因为这部分非常长且复杂) - } - - - // 如果seed参数为假(即没有提供初始的匹配元素集合) - if ( !seed ) { - - // 如果提供的上下文(context)不是当前文档,则设置文档为上下文 - // 如果没有提供上下文,则使用preferredDoc(优先文档)作为上下文 - // 如果上下文是一个元素,则使用它的ownerDocument(拥有它的文档)作为上下文 - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - // 如果没有提供上下文,则默认使用document作为上下文 - context = context || document; - - // 如果文档是HTML文档 - if ( documentIsHTML ) { - - // 如果选择器足够简单,尝试使用"get*By*" DOM方法(除了DocumentFragment上下文,因为DocumentFragment上没有这些方法) - if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { - - // ID选择器 - if ( (m = match[1]) ) { - - // 文档上下文 - if ( nodeType === 9 ) { - if ( (elem = context.getElementById( m )) ) { - // 支持:IE, Opera, Webkit - // TODO: 识别版本 - // getElementById可能会根据名称而不是ID匹配元素 - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - - // 元素上下文 - } else { - // 支持:IE, Opera, Webkit - // TODO: 识别版本 - // getElementById可能会根据名称而不是ID匹配元素 - if ( newContext && (elem = newContext.getElementById( m )) && - contains( context, elem ) && - elem.id === m ) { - - results.push( elem ); - return results; - } - } - - // 类型选择器 - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // 类选择器 - } else if ( (m = match[3]) && support.getElementsByClassName && - context.getElementsByClassName ) { - - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // 使用querySelectorAll - if ( support.qsa && - !compilerCache[ selector + " " ] && - (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - - if ( nodeType !== 1 ) { - newContext = context; - newSelector = selector; - - // qSA会在元素上下文之外查找,这不是我们想要的 - // 感谢Andrew Dupont提供的这种解决方法 - // 支持:IE <=8 - // 排除对象元素 - } else if ( context.nodeName.toLowerCase() !== "object" ) { - - // 捕获上下文的ID,如果必要则先设置它 - if ( (nid = context.getAttribute( "id" )) ) { - nid = nid.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", (nid = expando) ); - } - - // 在列表中的每个选择器前加上前缀 - groups = tokenize( selector ); - i = groups.length; - nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']"; - while ( i-- ) { - groups[i] = nidselect + " " + toSelector( groups[i] ); - } - newSelector = groups.join( "," ); - - // 为兄弟选择器扩展上下文 - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || - context; - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch ( qsaError ) { - } finally { - if ( nid === expando ) { - context.removeAttribute( "id" ); - } - } - } - } - } - - // 其他情况 - return select( selector.replace( rtrim, "$1" ), context, results, seed ); - } - - /** - * 创建一个有限大小的键值缓存 - * @returns {function(string, object)} 返回一个在存储后将数据对象存储在自身上的函数,属性名为(空格后缀)字符串, - * 如果缓存大于Expr.cacheLength,则删除最旧的条目 - */ - function createCache() { - var keys = []; - - function cache( key, value ) { - // 使用(key + " ")以避免与原生原型属性冲突(见Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // 仅保留最近的条目 - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; - } - - /** - * 为Sizzle特殊使用标记一个函数 - * @param {Function} fn 要标记的函数 - */ - function markFunction( fn ) { - fn[ expando ] = true; - return fn; - } - - /** - * 使用一个元素支持测试 - * @param {Function} fn 传入创建的div,并期望一个布尔结果 - */ - function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // 默认情况下从其父节点中移除 - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // 在IE中释放内存 - div = null; - } - } /** * 为指定的attrs添加相同的处理器