From df87ea8e2fdea9f8e406891cb20524a013b3d2e1 Mon Sep 17 00:00:00 2001 From: gyt <602050807@qq.com> Date: Wed, 18 Dec 2024 18:21:10 +0800 Subject: [PATCH] zhushi --- web/static/script/jquery-1.7.2.js | 897 +++++++++++++++--------------- 1 file changed, 454 insertions(+), 443 deletions(-) diff --git a/web/static/script/jquery-1.7.2.js b/web/static/script/jquery-1.7.2.js index 391f195..3a0c2ce 100644 --- a/web/static/script/jquery-1.7.2.js +++ b/web/static/script/jquery-1.7.2.js @@ -6844,505 +6844,516 @@ function getWidthOrHeight( elem, name, extra ) { return val + "px"; } -jQuery.each([ "height", "width" ], function( i, name ) { - jQuery.cssHooks[ name ] = { - get: function( elem, computed, extra ) { - if ( computed ) { - if ( elem.offsetWidth !== 0 ) { - return getWidthOrHeight( elem, name, extra ); - } else { - return jQuery.swap( elem, cssShow, function() { - return getWidthOrHeight( elem, name, extra ); - }); +// 遍历 height 和 width 数组,为它们添加 cssHooks + jQuery.each(["height", "width"], function (i, name) { + jQuery.cssHooks[name] = { + // 获取元素的 height 或 width 属性值 + get: function (elem, computed, extra) { + if (computed) { + // 如果元素的 offsetWidth 不为 0 + if (elem.offsetWidth!== 0) { + return getWidthOrHeight(elem, name, extra); + } else { + // 使用 jQuery.swap 方法临时设置元素的样式,然后获取属性值 + return jQuery.swap(elem, cssShow, function () { + return getWidthOrHeight(elem, name, extra); + }); + } } + }, + // 设置元素的 height 或 width 属性值 + set: function (elem, value) { + // 如果值是数字,添加 px 单位,否则直接返回 + return rnum.test(value)? value + "px" : value; } - }, - - set: function( elem, value ) { - return rnum.test( value ) ? - value + "px" : - value; - } - }; -}); - -if ( !jQuery.support.opacity ) { - jQuery.cssHooks.opacity = { - get: function( elem, computed ) { - // IE uses filters for opacity - return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? - ( parseFloat( RegExp.$1 ) / 100 ) + "" : - computed ? "1" : ""; - }, - - set: function( elem, value ) { - var style = elem.style, - currentStyle = elem.currentStyle, - opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", - filter = currentStyle && currentStyle.filter || style.filter || ""; - - // IE has trouble with opacity if it does not have layout - // Force it by setting the zoom level - style.zoom = 1; - - // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 - if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) { - - // Setting style.filter to null, "" & " " still leave "filter:" in the cssText - // if "filter:" is present at all, clearType is disabled, we want to avoid this - // style.removeAttribute is IE Only, but so apparently is this code path... - style.removeAttribute( "filter" ); + }; + }); - // if there there is no filter style applied in a css rule, we are done - if ( currentStyle && !currentStyle.filter ) { - return; +// 如果不支持 opacity,为 opacity 添加 cssHooks + if (!jQuery.support.opacity) { + jQuery.cssHooks.opacity = { + // 获取元素的 opacity 属性值 + get: function (elem, computed) { + // IE 使用 filters 来表示 opacity + return ropacity.test((computed && elem.currentStyle? elem.currentStyle.filter : elem.style.filter) || "")? + (parseFloat(RegExp.$1) / 100) + "" : + computed? "1" : ""; + }, + // 设置元素的 opacity 属性值 + set: function (elem, value) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric(value)? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE 对于没有布局的元素设置 opacity 会有问题,通过设置 zoom 来强制布局 + style.zoom = 1; + + // 如果设置 opacity 为 1,且没有其他过滤器存在,尝试移除 filter 属性 #6652 + if (value >= 1 && jQuery.trim(filter.replace(ralpha, "")) === "") { + // 设置 style.filter 为 null 或 "" 或 " " 仍然会在 cssText 中留下 "filter:",如果存在 "filter:",clearType 会被禁用,我们想要避免这个问题 + // style.removeAttribute 是 IE 特有的,但这段代码似乎只在 IE 中使用 + style.removeAttribute("filter"); + + // 如果没有在 css 规则中应用 filter 样式,完成操作 + if (currentStyle &&!currentStyle.filter) { + return; + } } - } - // otherwise, set new filter values - style.filter = ralpha.test( filter ) ? - filter.replace( ralpha, opacity ) : - filter + " " + opacity; - } - }; -} - -jQuery(function() { - // This hook cannot be added until DOM ready because the support test - // for it is not run until after DOM ready - if ( !jQuery.support.reliableMarginRight ) { - jQuery.cssHooks.marginRight = { - get: function( elem, computed ) { - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - // Work around by temporarily setting element display to inline-block - return jQuery.swap( elem, { "display": "inline-block" }, function() { - if ( computed ) { - return curCSS( elem, "margin-right" ); - } else { - return elem.style.marginRight; - } - }); + // 否则,设置新的 filter 值 + style.filter = ralpha.test(filter)? + filter.replace(ralpha, opacity) : + filter + " " + opacity; } }; } -}); - -if ( jQuery.expr && jQuery.expr.filters ) { - jQuery.expr.filters.hidden = function( elem ) { - var width = elem.offsetWidth, - height = elem.offsetHeight; - - return ( width === 0 && height === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); - }; - - jQuery.expr.filters.visible = function( elem ) { - return !jQuery.expr.filters.hidden( elem ); - }; -} - -// These hooks are used by animate to expand properties -jQuery.each({ - margin: "", - padding: "", - border: "Width" -}, function( prefix, suffix ) { - - jQuery.cssHooks[ prefix + suffix ] = { - expand: function( value ) { - var i, - // assumes a single number if not a string - parts = typeof value === "string" ? value.split(" ") : [ value ], - expanded = {}; - - for ( i = 0; i < 4; i++ ) { - expanded[ prefix + cssExpand[ i ] + suffix ] = - parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; - } - - return expanded; +// 在 DOM 加载完成后添加 marginRight 的 cssHook + jQuery(function () { + // 这个 hook 直到 DOM 加载完成后才能添加,因为对它的支持测试要在 DOM 加载完成后进行 + if (!jQuery.support.reliableMarginRight) { + jQuery.cssHooks.marginRight = { + // 获取元素的 marginRight 属性值 + get: function (elem, computed) { + // WebKit Bug 13343 - getComputedStyle 返回错误的 margin-right 值 + // 通过临时将元素的显示设置为 inline-block 来解决 + return jQuery.swap(elem, {"display": "inline-block"}, function () { + if (computed) { + return curCSS(elem, "margin-right"); + } else { + return elem.style.marginRight; + } + }); + } + }; } - }; -}); - - - - -var r20 = /%20/g, - rbracket = /\[\]$/, - rCRLF = /\r?\n/g, - rhash = /#.*$/, - rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL - rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, - // #7653, #8125, #8152: local protocol detection - rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, - rnoContent = /^(?:GET|HEAD)$/, - rprotocol = /^\/\//, - rquery = /\?/, - rscript = /)<[^<]*)*<\/script>/gi, - rselectTextarea = /^(?:select|textarea)/i, - rspacesAjax = /\s+/, - rts = /([?&])_=[^&]*/, - rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, - - // Keep a copy of the old load method - _load = jQuery.fn.load, - - /* Prefilters - * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) - * 2) These are called: - * - BEFORE asking for a transport - * - AFTER param serialization (s.data is a string if s.processData is true) - * 3) key is the dataType - * 4) the catchall symbol "*" can be used - * 5) execution will start with transport dataType and THEN continue down to "*" if needed - */ - prefilters = {}, - - /* Transports bindings - * 1) key is the dataType - * 2) the catchall symbol "*" can be used - * 3) selection will start with transport dataType and THEN go to "*" if needed - */ - transports = {}, + }); - // Document location - ajaxLocation, +// 检查 jQuery.expr 和 jQuery.expr.filters 是否存在 + if (jQuery.expr && jQuery.expr.filters) { + // 为 jQuery.expr.filters 添加 hidden 过滤器 + jQuery.expr.filters.hidden = function (elem) { + var width = elem.offsetWidth, + height = elem.offsetHeight; + // 判断元素是否隐藏,根据宽度和高度是否都为 0 或者不支持 reliableHiddenOffsets 且元素的显示为 none 来判断 + return (width === 0 && height === 0) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css(elem, "display")) === "none"); + }; + // 为 jQuery.expr.filters 添加 visible 过滤器,可见元素就是不隐藏的元素 + jQuery.expr.filters.visible = function (elem) { + return!jQuery.expr.filters.hidden(elem); + }; + } - // Document location segments - ajaxLocParts, +// 这些钩子被 animate 函数用来扩展属性 + jQuery.each({ + margin: "", + padding: "", + border: "Width" + }, function (prefix, suffix) { + jQuery.cssHooks[prefix + suffix] = { + // 扩展函数,将输入值扩展为包含四个方向属性的对象 + expand: function (value) { + var i, + // 如果不是字符串则假设是单个数字,否则将字符串按空格拆分为数组 + parts = typeof value === "string"? value.split(" ") : [value], + expanded = {}; + for (i = 0; i < 4; i++) { + expanded[prefix + cssExpand[i] + suffix] = + parts[i] || parts[i - 2] || parts[0]; + } + return expanded; + } + }; + }); - // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression - allTypes = ["*/"] + ["*"]; -// #8138, IE may throw an exception when accessing -// a field from window.location if document.domain has been set -try { - ajaxLocation = location.href; -} catch( e ) { - // Use the href attribute of an A element - // since IE will modify it given document.location - ajaxLocation = document.createElement( "a" ); - ajaxLocation.href = ""; - ajaxLocation = ajaxLocation.href; -} + var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE 在 EOL 处会留下一个 \r 字符 + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + // #7653, #8125, #8152: 本地协议检测 + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rselectTextarea = /^(?:select|textarea)/i, + rspacesAjax = /\s+/, + rts = /([?&])_=[^&]*/, + rurl = /^([\w+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?/, + // 保存旧的 load 方法 + _load = jQuery.fn.load, + // Prefilters + // 1) 它们可用于引入自定义数据类型(例如 ajax/jsonp.js 中的示例) + // 2) 它们在请求传输之前和参数序列化之后调用(如果 s.processData 为 true,则 s.data 是一个字符串) + // 3) key 是数据类型 + // 4) 通配符 "*" 可以使用 + // 5) 执行将从传输数据类型开始,然后根据需要继续到 "*" + prefilters = {}, + // Transports bindings + // 1) key 是数据类型 + // 2) 通配符 "*" 可以使用 + // 3) 选择将从传输数据类型开始,然后根据需要到 "*" + transports = {}, + // 文档位置 + ajaxLocation, + // 文档位置的部分 + ajaxLocParts, + // 避免注释序言字符序列 (#10098);必须满足 lint 并避免压缩 + allTypes = ["*/"] + ["*"]; + +// #8138, IE 可能在访问 window.location 的字段时抛出异常,如果 document.domain 已设置 + try { + // 获取 location.href + ajaxLocation = location.href; + } catch (e) { + // 使用 A 元素的 href 属性 + // 因为 IE 会根据 document.location 修改它 + ajaxLocation = document.createElement("a"); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; + } // Segment location into parts -ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; - -// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport -function addToPrefiltersOrTransports( structure ) { +// 执行 rurl 正则表达式匹配,将结果存储在 ajaxLocParts 中,如果没有匹配结果则存储空数组 + ajaxLocParts = rurl.exec(ajaxLocation.toLowerCase()) || []; - // dataTypeExpression is optional and defaults to "*" - return function( dataTypeExpression, func ) { - - if ( typeof dataTypeExpression !== "string" ) { - func = dataTypeExpression; - dataTypeExpression = "*"; - } - - if ( jQuery.isFunction( func ) ) { - var dataTypes = dataTypeExpression.toLowerCase().split( rspacesAjax ), - i = 0, - length = dataTypes.length, - dataType, - list, - placeBefore; +// jQuery.ajaxPrefilter 和 jQuery.ajaxTransport 的基础“构造函数” + function addToPrefiltersOrTransports(structure) { + // dataTypeExpression 是可选的,默认为 "*" + return function (dataTypeExpression, func) { + // 如果 dataTypeExpression 不是字符串,将 func 作为 dataTypeExpression,并将 dataTypeExpression 设为 "*" + if (typeof dataTypeExpression!== "string") { + func = dataTypeExpression; + dataTypeExpression = "*"; + } - // For each dataType in the dataTypeExpression - for ( ; i < length; i++ ) { - dataType = dataTypes[ i ]; - // We control if we're asked to add before - // any existing element - placeBefore = /^\+/.test( dataType ); - if ( placeBefore ) { - dataType = dataType.substr( 1 ) || "*"; + if (jQuery.isFunction(func)) { + var dataTypes = dataTypeExpression.toLowerCase().split(rspacesAjax), + i = 0, + length = dataTypes.length, + dataType, + list, + placeBefore; + + // 对于 dataTypeExpression 中的每个数据类型 + for (; i < length; i++) { + dataType = dataTypes[i]; + // 检查是否需要添加到已有元素之前 + placeBefore = /^\+/.test(dataType); + if (placeBefore) { + dataType = dataType.substr(1) || "*"; + } + // 获取或创建存储结构中对应的数据类型列表 + list = structure[dataType] = structure[dataType] || []; + // 根据 placeBefore 的情况将 func 添加到列表的开头或末尾 + list[placeBefore? "unshift" : "push"](func); } - list = structure[ dataType ] = structure[ dataType ] || []; - // then we add to the structure accordingly - list[ placeBefore ? "unshift" : "push" ]( func ); } - } - }; -} - -// Base inspection function for prefilters and transports -function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, - dataType /* internal */, inspected /* internal */ ) { - - dataType = dataType || options.dataTypes[ 0 ]; - inspected = inspected || {}; - - inspected[ dataType ] = true; + }; + } - var list = structure[ dataType ], - i = 0, - length = list ? list.length : 0, - executeOnly = ( structure === prefilters ), - selection; +// 预过滤器和传输器的基础检查函数 + function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */) { + dataType = dataType || options.dataTypes[0]; + inspected = inspected || {}; + // 标记已检查的数据类型 + inspected[dataType] = true; - for ( ; i < length && ( executeOnly || !selection ); i++ ) { - selection = list[ i ]( options, originalOptions, jqXHR ); - // If we got redirected to another dataType - // we try there if executing only and not done already - if ( typeof selection === "string" ) { - if ( !executeOnly || inspected[ selection ] ) { - selection = undefined; - } else { - options.dataTypes.unshift( selection ); - selection = inspectPrefiltersOrTransports( - structure, options, originalOptions, jqXHR, selection, inspected ); + var list = structure[dataType], + i = 0, + length = list? list.length : 0, + executeOnly = (structure === prefilters), + selection; + + for (; i < length && (executeOnly ||!selection); i++) { + selection = list[i](options, originalOptions, jqXHR); + // 如果重定向到另一个数据类型 + // 如果仅执行且尚未完成,则尝试新的数据类型 + if (typeof selection === "string") { + if (!executeOnly || inspected[selection]) { + selection = undefined; + } else { + options.dataTypes.unshift(selection); + // 递归调用自身检查新的数据类型 + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected); + } } } + // 如果仅执行或未选择任何内容,并且未检查过通配符数据类型 + if ((executeOnly ||!selection) &&!inspected["*"]) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected); + } + // 对于预过滤器不必要,但调用者会忽略 + return selection; } - // If we're only executing or nothing was selected - // we try the catchall dataType if not done already - if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { - selection = inspectPrefiltersOrTransports( - structure, options, originalOptions, jqXHR, "*", inspected ); - } - // unnecessary when only executing (prefilters) - // but it'll be ignored by the caller in that case - return selection; -} -// A special extend for ajax options -// that takes "flat" options (not to be deep extended) -// Fixes #9887 -function ajaxExtend( target, src ) { - var key, deep, - flatOptions = jQuery.ajaxSettings.flatOptions || {}; - for ( key in src ) { - if ( src[ key ] !== undefined ) { - ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; +// 一个特殊的 ajax 选项扩展函数 +// 接受“扁平”选项(不进行深度扩展) +// 修复 #9887 问题 + function ajaxExtend(target, src) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for (key in src) { + if (src[key]!== undefined) { + // 根据 flatOptions 决定是否进行深度扩展 + (flatOptions[key]? target : (deep || (deep = {})))[key] = src[key]; + } + } + if (deep) { + jQuery.extend(true, target, deep); } } - if ( deep ) { - jQuery.extend( true, target, deep ); - } -} -jQuery.fn.extend({ - load: function( url, params, callback ) { - if ( typeof url !== "string" && _load ) { - return _load.apply( this, arguments ); - - // Don't do a request if no elements are being requested - } else if ( !this.length ) { - return this; - } + jQuery.fn.extend({ + load: function (url, params, callback) { + // 如果 url 不是字符串且 _load 存在,使用 _load 函数 + if (typeof url!== "string" && _load) { + return _load.apply(this, arguments); + } + // 如果没有元素请求,不执行请求,直接返回 jQuery 对象 + else if (!this.length) { + return this; + } - var off = url.indexOf( " " ); - if ( off >= 0 ) { - var selector = url.slice( off, url.length ); - url = url.slice( 0, off ); - } - - // Default to a GET request - var type = "GET"; - - // If the second parameter was provided - if ( params ) { - // If it's a function - if ( jQuery.isFunction( params ) ) { - // We assume that it's the callback - callback = params; - params = undefined; - - // Otherwise, build a param string - } else if ( typeof params === "object" ) { - params = jQuery.param( params, jQuery.ajaxSettings.traditional ); - type = "POST"; - } - } - - var self = this; - - // Request the remote document - jQuery.ajax({ - url: url, - type: type, - dataType: "html", - data: params, - // Complete callback (responseText is used internally) - complete: function( jqXHR, status, responseText ) { - // Store the response as specified by the jqXHR object - responseText = jqXHR.responseText; - // If successful, inject the HTML into all the matched elements - if ( jqXHR.isResolved() ) { - // #4825: Get the actual response in case - // a dataFilter is present in ajaxSettings - jqXHR.done(function( r ) { - responseText = r; - }); - // See if a selector was specified - self.html( selector ? - // Create a dummy div to hold the results - jQuery("
") - // inject the contents of the document in, removing the scripts - // to avoid any 'Permission Denied' errors in IE - .append(responseText.replace(rscript, "")) + var off = url.indexOf(" "); + if (off >= 0) { + var selector = url.slice(off, url.length); + url = url.slice(0, off); + } - // Locate the specified elements - .find(selector) : + // 默认使用 GET 请求 + var type = "GET"; - // If not, just inject the full result - responseText ); + // 如果提供了第二个参数 + if (params) { + // 如果是函数,将其作为回调函数 + if (jQuery.isFunction(params)) { + callback = params; + params = undefined; } - - if ( callback ) { - self.each( callback, [ responseText, status, jqXHR ] ); + // 如果是对象,将其转换为参数字符串并使用 POST 请求 + else if (typeof params === "object") { + params = jQuery.param(params, jQuery.ajaxSettings.traditional); + type = "POST"; } } - }); - return this; - }, + var self = this; - serialize: function() { - return jQuery.param( this.serializeArray() ); - }, - - serializeArray: function() { - return this.map(function(){ - return this.elements ? jQuery.makeArray( this.elements ) : this; - }) - .filter(function(){ - return this.name && !this.disabled && - ( this.checked || rselectTextarea.test( this.nodeName ) || - rinput.test( this.type ) ); - }) - .map(function( i, elem ){ - var val = jQuery( this ).val(); - - return val == null ? - null : - jQuery.isArray( val ) ? - jQuery.map( val, function( val, i ){ - return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }) : - { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; - }).get(); - } -}); +// Request the remote document + jQuery.ajax({ + // 请求的 URL + url: url, + // 请求的类型,默认为 GET 或根据前面的处理设置为 POST + type: type, + // 期望的数据类型为 HTML + dataType: "html", + // 请求的数据,可能是参数 + data: params, + // 完成回调函数 + complete: function (jqXHR, status, responseText) { + // 将响应存储为 jqXHR 对象指定的内容 + responseText = jqXHR.responseText; + // 如果请求成功 + if (jqXHR.isResolved()) { + // #4825: 获取实际的响应,以防 ajaxSettings 中存在数据过滤器 + jqXHR.done(function (r) { + responseText = r; + }); + // 检查是否指定了选择器 + self.html(selector? + // 创建一个虚拟的 div 来存储结果 + jQuery("
") + // 注入文档内容,移除脚本以避免 IE 中的 'Permission Denied' 错误 + .append(responseText.replace(rscript, "")) + // 查找指定的元素 + .find(selector) : + // 如果没有指定选择器,直接注入完整的结果 + responseText); + } -// Attach a bunch of functions for handling common AJAX events -jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ - jQuery.fn[ o ] = function( f ){ - return this.on( o, f ); - }; -}); + if (callback) { + // 为每个元素执行回调函数,传递响应文本、状态和 jqXHR 对象 + self.each(callback, [responseText, status, jqXHR]); + } + } + }); -jQuery.each( [ "get", "post" ], function( i, method ) { - jQuery[ method ] = function( url, data, callback, type ) { - // shift arguments if data argument was omitted - if ( jQuery.isFunction( data ) ) { - type = type || callback; - callback = data; - data = undefined; - } +// 返回 jQuery 对象本身 + return this; + }, + +// serialize 函数,将表单元素序列化为字符串 + serialize: function () { + // 使用 jQuery.param 对序列化数组的结果进行处理 + return jQuery.param(this.serializeArray()); + }, - return jQuery.ajax({ - type: method, - url: url, - data: data, - success: callback, - dataType: type +// serializeArray 函数,将表单元素序列化为数组 + serializeArray: function () { + return this.map(function () { + // 对于元素集合中的元素,如果有 elements 属性则转换为数组,否则保持不变 + return this.elements? jQuery.makeArray(this.elements) : this; + }) + // 过滤元素,只保留满足条件的元素 + .filter(function () { + return this.name &&!this.disabled && + (this.checked || rselectTextarea.test(this.nodeName) || + rinput.test(this.type)); + }) + // 映射元素,将元素转换为对象,处理元素的值 + .map(function (i, elem) { + var val = jQuery(this).val(); + return val == null? + null : + jQuery.isArray(val)? + // 对于数组类型的值,为每个元素创建对象 + jQuery.map(val, function (val, i) { + return {name: elem.name, value: val.replace(rCRLF, "\r\n")}; + }) : + // 对于非数组类型的值,创建对象 + {name: elem.name, value: val.replace(rCRLF, "\r\n")}; + }).get(); }); - }; -}); -jQuery.extend({ +// 为处理常见的 AJAX 事件附加一系列函数 + jQuery.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function (i, o) { + // 为 jQuery.fn 扩展事件处理函数,调用 on 方法添加事件监听器 + jQuery.fn[o] = function (f) { + return this.on(o, f); + }; + }); - getScript: function( url, callback ) { - return jQuery.get( url, undefined, callback, "script" ); - }, + jQuery.each(["get", "post"], function (i, method) { + // 为 jQuery 扩展 get 和 post 方法 + jQuery[method] = function (url, data, callback, type) { + // 如果数据参数被省略,调整参数顺序 + if (jQuery.isFunction(data)) { + type = type || callback; + callback = data; + data = undefined; + } - getJSON: function( url, data, callback ) { - return jQuery.get( url, data, callback, "json" ); - }, + // 发起 AJAX 请求 + return jQuery.ajax({ + type: method, + url: url, + data: data, + // 成功回调函数 + success: callback, + dataType: type + }); + }; + }); + jQuery.extend({ - // Creates a full fledged settings object into target - // with both ajaxSettings and settings fields. - // If target is omitted, writes into ajaxSettings. - ajaxSetup: function( target, settings ) { - if ( settings ) { - // Building a settings object - ajaxExtend( target, jQuery.ajaxSettings ); - } else { - // Extending ajaxSettings - settings = target; - target = jQuery.ajaxSettings; - } - ajaxExtend( target, settings ); - return target; - }, - - ajaxSettings: { - url: ajaxLocation, - isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), - global: true, - type: "GET", - contentType: "application/x-www-form-urlencoded; charset=UTF-8", - processData: true, - async: true, - /* - timeout: 0, - data: null, - dataType: null, - username: null, - password: null, - cache: null, - traditional: false, - headers: {}, - */ - - accepts: { - xml: "application/xml, text/xml", - html: "text/html", - text: "text/plain", - json: "application/json, text/javascript", - "*": allTypes + // getScript 函数,用于获取脚本资源 + getScript: function (url, callback) { + // 调用 jQuery.get 方法,指定数据类型为 script + return jQuery.get(url, undefined, callback, "script"); }, - contents: { - xml: /xml/, - html: /html/, - json: /json/ + // getJSON 函数,用于获取 JSON 资源 + getJSON: function (url, data, callback) { + // 调用 jQuery.get 方法,指定数据类型为 json + return jQuery.get(url, data, callback, "json"); }, - responseFields: { - xml: "responseXML", - text: "responseText" + // ajaxSetup 函数,创建完整的设置对象,可对 ajaxSettings 进行扩展或更新 + ajaxSetup: function (target, settings) { + if (settings) { + // 构建一个新的设置对象,将 ajaxSettings 扩展到 target 中 + ajaxExtend(target, jQuery.ajaxSettings); + } else { + // 如果没有 settings 参数,将 target 视为 settings,将 ajaxSettings 作为目标扩展对象 + settings = target; + target = jQuery.ajaxSettings; + } + // 扩展目标对象,将 settings 的属性添加到目标对象中 + ajaxExtend(target, settings); + return target; }, - // List of data converters - // 1) key format is "source_type destination_type" (a single space in-between) - // 2) the catchall symbol "*" can be used for source_type - converters: { + ajaxSettings: { + // 请求的默认 URL + url: ajaxLocation, + // 判断是否为本地请求 + isLocal: rlocalProtocol.test(ajaxLocParts[1]), + // 全局标志,默认为 true + global: true, + // 请求的默认类型为 GET + type: "GET", + // 默认的内容类型 + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + // 是否处理数据,默认为 true + processData: true, + // 请求是否异步,默认为 true + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + traditional: false, + headers: {}, + */ + + accepts: { + // 不同数据类型的可接受内容 + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, - // Convert anything to text - "* text": window.String, + contents: { + // 不同数据类型的内容匹配规则 + xml: /xml/, + html: /html/, + json: /json/ + }, - // Text to html (true = no transformation) - "text html": true, + responseFields: { + // 不同数据类型对应的响应字段 + xml: "responseXML", + text: "responseText" + }, - // Evaluate text as a json expression - "text json": jQuery.parseJSON, + // 数据转换器列表 + // 1) 键的格式是 "source_type destination_type"(中间有一个空格) + // 2) 通配符 "*" 可用于 source_type + converters: { - // Parse text as xml - "text xml": jQuery.parseXML - }, + // 将任何类型转换为文本 + "* text": window.String, - // For options that shouldn't be deep extended: - // you can add your own custom options here if - // and when you create one that shouldn't be - // deep extended (see ajaxExtend) - flatOptions: { - context: true, - url: true - } - }, + // 将文本转换为 html(true 表示无转换) + "text html": true, + + // 将文本解析为 json 表达式 + "text json": jQuery.parseJSON, + + // 将文本解析为 xml + "text xml": jQuery.parseXML + }, + + // 对于不应该深度扩展的选项: + // 你可以在此处添加自己的自定义选项,当你创建一个不应该深度扩展的选项时(见 ajaxExtend 函数) + flatOptions: { + context: true, + url: true + } + }, ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), ajaxTransport: addToPrefiltersOrTransports( transports ),