From 677cd46203b463aed8256147bd0dcfec0f510b06 Mon Sep 17 00:00:00 2001 From: gyt <602050807@qq.com> Date: Wed, 18 Dec 2024 17:39:51 +0800 Subject: [PATCH] zhushi --- web/static/script/3.text | 1 + web/static/script/jquery-1.7.2.js | 548 +++++++++++++++++++----------- 2 files changed, 356 insertions(+), 193 deletions(-) create mode 100644 web/static/script/3.text diff --git a/web/static/script/3.text b/web/static/script/3.text new file mode 100644 index 0000000..d28d40b --- /dev/null +++ b/web/static/script/3.text @@ -0,0 +1 @@ +add \ No newline at end of file diff --git a/web/static/script/jquery-1.7.2.js b/web/static/script/jquery-1.7.2.js index 80bfc5e..64b566a 100644 --- a/web/static/script/jquery-1.7.2.js +++ b/web/static/script/jquery-1.7.2.js @@ -8558,34 +8558,34 @@ for ( name in prop ) { val = prop[ name ]; // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) + // 缓动的处理逻辑:根据每个属性 > opt.specialEasing > opt.easing > 'swing'(默认) if ( jQuery.isArray( val ) ) { + // 如果 val 是数组,将 opt.animatedProperties 中 name 对应的属性设置为 val[1] opt.animatedProperties[ name ] = val[ 1 ]; + // 将 prop 中 name 对应的属性设置为 val[0] val = prop[ name ] = val[ 0 ]; } else { - opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; + // 否则,设置 opt.animatedProperties 中 name 对应的属性为 opt.specialEasing 中 name 对应的属性,如果不存在则使用 opt.easing,再不存在使用'swing' + opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing ||'swing'; } - if ( val === "hide" && hidden || val === "show" && !hidden ) { + // 如果 val 是 'hide' 且 hidden 为真,或者 val 是'show' 且 hidden 为假,调用 opt.complete 函数 + if ( val === "hide" && hidden || val === "show" &&!hidden ) { return opt.complete.call( this ); } if ( isElement && ( name === "height" || name === "width" ) ) { - // Make sure that nothing sneaks out - // Record all 3 overflow attributes because IE does not - // change the overflow attribute when overflowX and - // overflowY are set to the same value + // 确保没有遗漏 + // 记录所有 3 个 overflow 属性,因为 IE 在 overflowX 和 overflowY 被设置为相同值时不会改变 overflow 属性 opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; - // Set display property to inline-block for height/width - // animations on inline elements that are having width/height animated + // 对于内联元素,当动画 width 或 height 时,将 display 属性设置为 inline-block if ( jQuery.css( this, "display" ) === "inline" && jQuery.css( this, "float" ) === "none" ) { - // inline-level elements accept inline-block; - // block-level elements need to be inline with layout - if ( !jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { + // 内联元素使用 inline-block;块级元素需要 inline 布局 + if (!jQuery.support.inlineBlockNeedsLayout || defaultDisplay( this.nodeName ) === "inline" ) { this.style.display = "inline-block"; - } else { this.style.zoom = 1; } @@ -8593,424 +8593,530 @@ } } - if ( opt.overflow != null ) { +// 如果 opt.overflow 不为 null,将元素的 overflow 属性设置为 "hidden" + if ( opt.overflow!= null ) { this.style.overflow = "hidden"; } for ( p in prop ) { + // 创建 jQuery.fx 对象 e = new jQuery.fx( this, opt, p ); val = prop[ p ]; if ( rfxtypes.test( val ) ) { - - // Tracks whether to show or hide based on private - // data attached to the element - method = jQuery._data( this, "toggle" + p ) || ( val === "toggle" ? hidden ? "show" : "hide" : 0 ); + // 根据元素的私有数据来决定是显示还是隐藏 + method = jQuery._data( this, "toggle" + p ) || ( val === "toggle"? hidden? "show" : "hide" : 0 ); if ( method ) { - jQuery._data( this, "toggle" + p, method === "show" ? "hide" : "show" ); + // 存储 toggle 数据 + jQuery._data( this, "toggle" + p, method === "show"? "hide" : "show" ); + // 调用相应的 show 或 hide 方法 e[ method ](); } else { + // 调用 val 对应的方法 e[ val ](); } - } else { parts = rfxnum.exec( val ); start = e.cur(); if ( parts ) { + // 获取最终值和单位 end = parseFloat( parts[2] ); - unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); + unit = parts[3] || ( jQuery.cssNumber[ p ]? "" : "px" ); - // We need to compute starting value - if ( unit !== "px" ) { + // 计算起始值 + if ( unit!== "px" ) { jQuery.style( this, p, (end || 1) + unit); start = ( (end || 1) / e.cur() ) * start; jQuery.style( this, p, start + unit); } - // If a +=/-= token was provided, we're doing a relative animation + // 如果有 += 或 -= 标记,进行相对动画 if ( parts[1] ) { - end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; + end = ( (parts[ 1 ] === "-="? -1 : 1) * end ) + start; } + // 调用 custom 方法进行自定义动画 e.custom( start, end, unit ); - } else { + // 调用 custom 方法进行自定义动画,使用默认单位 e.custom( start, val, "" ); } } } - // For JS strict compliance +// 为了符合 JS 严格模式 return true; } - return optall.queue === false ? +// 根据 optall.queue 是否为 false 决定执行动画的方式 + return optall.queue === false? this.each( doAnimation ) : this.queue( optall.queue, doAnimation ); - }, stop: function( type, clearQueue, gotoEnd ) { - if ( typeof type !== "string" ) { + // 如果 type 不是字符串,重新分配参数 + if ( typeof type!== "string" ) { gotoEnd = clearQueue; clearQueue = type; type = undefined; } - if ( clearQueue && type !== false ) { + // 如果 clearQueue 为真且 type 不为 false,将相应队列清空 + if ( clearQueue && type!== false ) { this.queue( type || "fx", [] ); } + // 对集合中的每个元素进行操作 return this.each(function() { var index, hadTimers = false, timers = jQuery.timers, data = jQuery._data( this ); - // clear marker counters if we know they won't be - if ( !gotoEnd ) { + // 如果不跳转到结束,清除标记计数器 + if (!gotoEnd ) { jQuery._unmark( true, this ); } + // 定义 stopQueue 函数,用于停止队列 function stopQueue( elem, data, index ) { var hooks = data[ index ]; + // 移除元素上的 index 数据 jQuery.removeData( elem, index, true ); + // 调用 hooks 的 stop 方法,可能是停止动画 hooks.stop( gotoEnd ); } + // 如果 type 为 null if ( type == null ) { + // 遍历 data 中的每个属性 for ( index in data ) { + // 如果属性存在且有 stop 方法且 index 以.run 结尾 if ( data[ index ] && data[ index ].stop && index.indexOf(".run") === index.length - 4 ) { + // 调用 stopQueue 函数 stopQueue( this, data, index ); } } } else if ( data[ index = type + ".run" ] && data[ index ].stop ){ + // 如果存在 type + ".run" 且有 stop 方法,调用 stopQueue 函数 stopQueue( this, data, index ); } + // 遍历定时器数组 for ( index = timers.length; index--; ) { + // 如果定时器元素是当前元素且满足类型条件 if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { if ( gotoEnd ) { - - // force the next step to be the last + // 强制下一个步骤为最后一步 timers[ index ]( true ); } else { + // 保存定时器状态 timers[ index ].saveState(); } hadTimers = true; + // 从定时器数组中移除该定时器 timers.splice( index, 1 ); } } - // start the next in the queue if the last step wasn't forced - // timers currently will call their complete callbacks, which will dequeue - // but only if they were gotoEnd - if ( !( gotoEnd && hadTimers ) ) { + // 如果没有强制最后一步,开始队列中的下一个任务 + if (!( gotoEnd && hadTimers ) ) { jQuery.dequeue( this, type ); } }); } - }); - // Animations created synchronously will run synchronously + // 创建当前动画时间的函数 function createFxNow() { - setTimeout( clearFxNow, 0 ); - return ( fxNow = jQuery.now() ); + // 立即调用 clearFxNow 函数,延迟时间为 0 + setTimeout(clearFxNow, 0); + // 调用 jQuery.now 函数获取当前时间并赋值给 fxNow,同时将结果返回 + return (fxNow = jQuery.now()); } +// 清除 fxNow 变量的函数 function clearFxNow() { + // 将 fxNow 设为 undefined fxNow = undefined; } -// Generate parameters to create a standard animation - function genFx( type, num ) { +// 生成创建标准动画的参数的函数 + function genFx(type, num) { var obj = {}; - - jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice( 0, num )), function() { - obj[ this ] = type; + // 使用 jQuery.each 方法遍历 fxAttrs 数组及其中的元素 + jQuery.each(fxAttrs.concat.apply([], fxAttrs.slice(0, num)), function () { + // 将对象的属性设置为传入的 type + obj[this] = type; }); - + // 返回生成的对象 return obj; } -// Generate shortcuts for custom animations +// 为自定义动画生成快捷方式 jQuery.each({ - slideDown: genFx( "show", 1 ), - slideUp: genFx( "hide", 1 ), - slideToggle: genFx( "toggle", 1 ), - fadeIn: { opacity: "show" }, - fadeOut: { opacity: "hide" }, - fadeToggle: { opacity: "toggle" } - }, function( name, props ) { - jQuery.fn[ name ] = function( speed, easing, callback ) { - return this.animate( props, speed, easing, callback ); + // 生成 slideDown 动画的参数 + slideDown: genFx("show", 1), + // 生成 slideUp 动画的参数 + slideUp: genFx("hide", 1), + // 生成 slideToggle 动画的参数 + slideToggle: genFx("toggle", 1), + // 生成 fadeIn 动画的参数,将 opacity 属性设置为 show + fadeIn: {opacity: "show"}, + // 生成 fadeOut 动画的参数,将 opacity 属性设置为 hide + fadeOut: {opacity: "hide"}, + // 生成 fadeToggle 动画的参数,将 opacity 属性设置为 toggle + fadeToggle: {opacity: "toggle"} + }, function (name, props) { + // 为 jQuery.fn 对象添加相应的方法,例如 slideDown、slideUp 等 + jQuery.fn[name] = function (speed, easing, callback) { + // 调用 animate 方法执行动画 + return this.animate(props, speed, easing, callback); }; }); jQuery.extend({ - speed: function( speed, easing, fn ) { - var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { - complete: fn || !fn && easing || - jQuery.isFunction( speed ) && speed, + // 定义 speed 函数,用于处理动画速度相关的配置 + speed: function (speed, easing, fn) { + // 如果 speed 是对象,则扩展一个空对象并赋值给 opt,否则根据 speed、easing 和 fn 来创建 opt 对象 + var opt = speed && typeof speed === "object"? jQuery.extend({}, speed) : { + complete: fn ||!fn && easing || + jQuery.isFunction(speed) && speed, duration: speed, - easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + easing: fn && easing || easing &&!jQuery.isFunction(easing) && easing }; - opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : - opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + // 如果 jQuery.fx.off 为真,则持续时间设为 0,否则根据不同情况设置持续时间 + opt.duration = jQuery.fx.off? 0 : typeof opt.duration === "number"? opt.duration : + opt.duration in jQuery.fx.speeds? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; - // normalize opt.queue - true/undefined/null -> "fx" - if ( opt.queue == null || opt.queue === true ) { + // 规范化 opt.queue 的值,将 true、undefined 或 null 规范化为 "fx" + if (opt.queue == null || opt.queue === true) { opt.queue = "fx"; } - // Queueing + // 队列操作 opt.old = opt.complete; - opt.complete = function( noUnmark ) { - if ( jQuery.isFunction( opt.old ) ) { - opt.old.call( this ); + // 重新定义 complete 函数 + opt.complete = function (noUnmark) { + // 如果 opt.old 是函数,调用它 + if (jQuery.isFunction(opt.old)) { + opt.old.call(this); } - if ( opt.queue ) { - jQuery.dequeue( this, opt.queue ); - } else if ( noUnmark !== false ) { - jQuery._unmark( this ); + // 如果存在队列,执行出队操作 + if (opt.queue) { + jQuery.dequeue(this, opt.queue); + } else if (noUnmark!== false) { + // 否则执行 _unmark 操作 + jQuery._unmark(this); } }; + // 返回配置对象 opt return opt; }, + // 定义 easing 函数,包含线性和摆动的缓动函数 easing: { - linear: function( p ) { + // 线性缓动函数,直接返回输入的参数 p + linear: function (p) { return p; }, - swing: function( p ) { - return ( -Math.cos( p*Math.PI ) / 2 ) + 0.5; + // 摆动缓动函数,根据输入的参数 p 进行计算 + swing: function (p) { + return (-Math.cos(p * Math.PI) / 2) + 0.5; } }, + // 存储定时器的数组 timers: [], - fx: function( elem, options, prop ) { + // 定义 fx 函数,用于创建一个 fx 对象 + fx: function (elem, options, prop) { + // 将传入的选项赋值给 this.options this.options = options; + // 将传入的元素赋值给 this.elem this.elem = elem; + // 将传入的属性赋值给 this.prop this.prop = prop; + // 确保 options.orig 存在,如果不存在则初始化为空对象 options.orig = options.orig || {}; } - }); jQuery.fx.prototype = { // Simple function for setting a style value + // 更新函数,用于更新样式的值 update: function() { - if ( this.options.step ) { - this.options.step.call( this.elem, this.now, this ); + // 如果存在 options.step 函数,调用它并将 this.elem 和 this 作为参数传递 + if (this.options.step) { + this.options.step.call(this.elem, this.now, this); } - - ( jQuery.fx.step[ this.prop ] || jQuery.fx.step._default )( this ); + // 调用 jQuery.fx 中对应的 step 函数,如果没有对应属性的 step 函数,则调用默认的 step 函数 + (jQuery.fx.step[this.prop] || jQuery.fx.step._default)(this); }, // Get the current size + // 获取当前大小的函数 cur: function() { - if ( this.elem[ this.prop ] != null && (!this.elem.style || this.elem.style[ this.prop ] == null) ) { - return this.elem[ this.prop ]; + // 如果元素的属性值不为空且元素没有样式或者元素的样式中该属性为空 + if (this.elem[this.prop]!= null && (!this.elem.style || this.elem.style[this.prop] == null)) { + // 返回元素的该属性值 + return this.elem[this.prop]; } var parsed, - r = jQuery.css( this.elem, this.prop ); + // 使用 jQuery.css 函数获取元素该属性的样式值 + r = jQuery.css(this.elem, this.prop); // Empty strings, null, undefined and "auto" are converted to 0, // complex values such as "rotate(1rad)" are returned as is, // simple values such as "10px" are parsed to Float. - return isNaN( parsed = parseFloat( r ) ) ? !r || r === "auto" ? 0 : r : parsed; + // 将解析后的结果存储在 parsed 中,如果解析结果是 NaN 且 r 为空或为 "auto" 则返回 0,否则返回 r,否则返回解析结果 + return isNaN(parsed = parseFloat(r))? (!r || r === "auto"? 0 : r) : parsed; }, // Start an animation from one number to another - custom: function( from, to, unit ) { + // 从一个数开始到另一个数开始动画的函数 + custom: function(from, to, unit) { var self = this, fx = jQuery.fx; + // 记录动画开始时间,使用 fxNow 或 createFxNow 函数获取 this.startTime = fxNow || createFxNow(); + // 结束值设置为 to this.end = to; + // 初始的当前值和起始值设置为 from this.now = this.start = from; - this.pos = this.state = 0; - this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); + // 设置单位,如果传入了 unit 则使用 unit,否则使用默认的单位,对于 jQuery.cssNumber 中存在的属性不使用单位,其他情况使用 "px" + this.unit = unit || this.unit || (jQuery.cssNumber[this.prop]? "" : "px"); - function t( gotoEnd ) { - return self.step( gotoEnd ); + // 定义内部函数 t,调用 self.step 函数 + function t(gotoEnd) { + return self.step(gotoEnd); } + // 为 t 函数添加 queue 属性,设置为 this.options.queue t.queue = this.options.queue; + // 为 t 函数添加 elem 属性,设置为 this.elem t.elem = this.elem; + // 为 t 函数添加 saveState 方法 t.saveState = function() { - if ( jQuery._data( self.elem, "fxshow" + self.prop ) === undefined ) { - if ( self.options.hide ) { - jQuery._data( self.elem, "fxshow" + self.prop, self.start ); - } else if ( self.options.show ) { - jQuery._data( self.elem, "fxshow" + self.prop, self.end ); + // 如果元素上没有存储 "fxshow" + self.prop 数据 + if (jQuery._data(self.elem, "fxshow" + self.prop) === undefined) { + // 如果是隐藏操作,存储起始值 + if (self.options.hide) { + jQuery._data(self.elem, "fxshow" + self.prop, self.start); + } else if (self.options.show) { + // 如果是显示操作,存储结束值 + jQuery._data(self.elem, "fxshow" + self.prop, self.end); } } }; - if ( t() && jQuery.timers.push(t) && !timerId ) { - timerId = setInterval( fx.tick, fx.interval ); + // 调用 t 函数,如果结果为真且将 t 函数添加到 jQuery.timers 数组中且 timerId 不存在 + if (t() && jQuery.timers.push(t) &&!timerId) { + // 启动定时器,调用 fx.tick 函数,时间间隔为 fx.interval + timerId = setInterval(fx.tick, fx.interval); } - }, + } + }; // Simple 'show' function show: function() { + // 获取元素上存储的 "fxshow" + this.prop 数据 var dataShow = jQuery._data( this.elem, "fxshow" + this.prop ); - // Remember where we started, so that we can go back to it later + // 记住开始的状态,以便之后可以恢复,将其存储在 options.orig[this.prop] 中,如果 dataShow 存在则使用 dataShow,否则使用元素的当前属性值 this.options.orig[ this.prop ] = dataShow || jQuery.style( this.elem, this.prop ); + // 标记为显示操作 this.options.show = true; - // Begin the animation - // Make sure that we start at a small width/height to avoid any flash of content - if ( dataShow !== undefined ) { - // This show is picking up where a previous hide or show left off + // 开始动画 + // 确保开始时使用较小的宽度/高度以避免内容闪烁 + if ( dataShow!== undefined ) { + // 这个显示操作是从之前的隐藏或显示操作中断的地方继续 this.custom( this.cur(), dataShow ); } else { - this.custom( this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur() ); + // 根据属性是否为宽度或高度,设置不同的起始值 + this.custom( this.prop === "width" || this.prop === "height"? 1 : 0, this.cur() ); } - // Start by showing the element + // 首先显示元素 jQuery( this.elem ).show(); }, - // Simple 'hide' function +// 简单的 'hide' 函数 hide: function() { - // Remember where we started, so that we can go back to it later + // 记住开始的状态,以便之后可以恢复,将其存储在 options.orig[this.prop] 中,如果存储的数据存在则使用存储的数据,否则使用元素的当前属性值 this.options.orig[ this.prop ] = jQuery._data( this.elem, "fxshow" + this.prop ) || jQuery.style( this.elem, this.prop ); + // 标记为隐藏操作 this.options.hide = true; - // Begin the animation + // 开始动画 this.custom( this.cur(), 0 ); }, - // Each step of an animation +// 动画的每一步 step: function( gotoEnd ) { var p, n, complete, + // 获取当前时间,若 fxNow 存在则使用 fxNow,否则调用 createFxNow 方法获取 t = fxNow || createFxNow(), done = true, elem = this.elem, options = this.options; + // 如果 gotoEnd 为真或当前时间大于等于持续时间加开始时间 if ( gotoEnd || t >= options.duration + this.startTime ) { + // 将 this.now 设置为结束值 this.now = this.end; + // 将 this.pos 和 this.state 都设置为 1 this.pos = this.state = 1; + // 执行更新操作 this.update(); + // 标记当前属性的动画已完成 options.animatedProperties[ this.prop ] = true; + // 遍历 animatedProperties 中的每个属性 for ( p in options.animatedProperties ) { - if ( options.animatedProperties[ p ] !== true ) { + // 如果该属性的动画未完成 + if ( options.animatedProperties[ p ]!== true ) { + // 标记为未完成 done = false; } } - + } if ( done ) { - // Reset the overflow - if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { - + // 如果 done 为 true + // 重置溢出属性 + if ( options.overflow!= null &&!jQuery.support.shrinkWrapBlocks ) { + // 使用 jQuery.each 方法遍历数组 ["", "X", "Y"] jQuery.each( [ "", "X", "Y" ], function( index, value ) { + // 将 elem 的 overflow 属性及其变体(overflowX、overflowY)设置为 options.overflow 数组中相应索引的值 elem.style[ "overflow" + value ] = options.overflow[ index ]; }); } - // Hide the element if the "hide" operation was done + // 如果是执行了 "hide" 操作,将元素隐藏 if ( options.hide ) { jQuery( elem ).hide(); } - // Reset the properties, if the item has been hidden or shown + // 如果执行了 "hide" 或 "show" 操作,重置相关属性 if ( options.hide || options.show ) { + // 遍历 options.animatedProperties 对象的属性 for ( p in options.animatedProperties ) { + // 将元素的属性 p 重置为 options.orig[p] 的值 jQuery.style( elem, p, options.orig[ p ] ); + // 移除元素上的 "fxshow" + p 数据 jQuery.removeData( elem, "fxshow" + p, true ); - // Toggle data is no longer needed + // 移除元素上的 "toggle" + p 数据 jQuery.removeData( elem, "toggle" + p, true ); } } - // Execute the complete function - // in the event that the complete function throws an exception - // we must ensure it won't be called twice. #5684 - + // 执行完成函数 + // 若完成函数抛出异常,确保它不会被调用两次,解决 #5684 问题 complete = options.complete; if ( complete ) { - + // 将 options.complete 设为 false options.complete = false; + // 以 elem 作为上下文调用 complete 函数 complete.call( elem ); } } +// 返回 false return false; } else { - // classical easing cannot be used with an Infinity duration + // 如果 duration 为 Infinity,经典的缓动效果无法使用 if ( options.duration == Infinity ) { + // 将 this.now 设置为 t this.now = t; } else { + // 计算动画已运行的时间 n n = t - this.startTime; + // 计算动画的状态(已运行时间 / 总时长) this.state = n / options.duration; - // Perform the easing function, defaults to swing + // 执行缓动函数,默认使用 swing 函数 this.pos = jQuery.easing[ options.animatedProperties[this.prop] ]( this.state, n, 0, 1, options.duration ); + // 计算当前的动画值 this.now = this.start + ( (this.end - this.start) * this.pos ); } - // Perform the next step of the animation + // 执行动画的下一步更新 this.update(); } +// 返回 true return true; - } - }; + // 使用 jQuery.extend 方法扩展 jQuery.fx 对象 jQuery.extend( jQuery.fx, { + // 定义 tick 函数 tick: function() { + // 定义 timer 变量和 timers 数组,以及索引 i 并初始化为 0 var timer, timers = jQuery.timers, i = 0; + // 遍历 timers 数组 for ( ; i < timers.length; i++ ) { + // 获取当前的定时器 timer = timers[ i ]; - // Checks the timer has not already been removed - if ( !timer() && timers[ i ] === timer ) { + // 检查定时器尚未被移除,如果定时器函数的返回值为 false 且 timers[i] 仍然是当前的 timer + if (!timer() && timers[ i ] === timer ) { + // 从 timers 数组中移除该定时器,并将索引 i 减 1 timers.splice( i--, 1 ); } } - if ( !timers.length ) { + // 如果 timers 数组的长度为 0 + if (!timers.length ) { + // 调用 jQuery.fx.stop 方法 jQuery.fx.stop(); } }, + // 定义动画的时间间隔为 13 毫秒 interval: 13, + // 定义 stop 函数 stop: function() { + // 清除定时器 clearInterval( timerId ); + // 将 timerId 设为 null timerId = null; }, + // 定义速度对象,包含 slow、fast 和默认速度 speeds: { slow: 600, fast: 200, - // Default speed + // 默认速度为 400 毫秒 _default: 400 }, + // 定义 step 对象,包含不同动画效果的处理函数 step: { + // 处理透明度的动画函数 opacity: function( fx ) { + // 使用 jQuery.style 方法设置元素的透明度为 fx.now 的值 jQuery.style( fx.elem, "opacity", fx.now ); }, + // 默认的动画处理函数 _default: function( fx ) { - if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) { + // 如果元素的样式存在且元素的样式属性存在 + if ( fx.elem.style && fx.elem.style[ fx.prop ]!= null ) { + // 设置元素的样式属性值为 fx.now + fx.unit fx.elem.style[ fx.prop ] = fx.now + fx.unit; } else { + // 否则设置元素的属性值为 fx.now fx.elem[ fx.prop ] = fx.now; } } @@ -9036,136 +9142,192 @@ } // Try to restore the default display value of an element - function defaultDisplay( nodeName ) { - - if ( !elemdisplay[ nodeName ] ) { - + function defaultDisplay(nodeName) { + // 检查 elemdisplay 中是否不存在以 nodeName 为键的值 + if (!elemdisplay[nodeName]) { + // 获取文档的 body 元素 var body = document.body, - elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), - display = elem.css( "display" ); + // 创建一个 jQuery 对象,元素为 并添加到 body 中 + elem = jQuery("<" + nodeName + ">").appendTo(body), + // 获取元素的 display 样式 + display = elem.css("display"); + // 移除该元素 elem.remove(); - // If the simple way fails, - // get element's real default display by attaching it to a temp iframe - if ( display === "none" || display === "" ) { - // No iframe to use yet, so create it - if ( !iframe ) { - iframe = document.createElement( "iframe" ); + // 如果简单的方式失败,通过将元素附加到临时 iframe 来获取元素真正的默认显示 + if (display === "none" || display === "") { + // 如果还没有 iframe,创建一个 iframe 元素 + if (!iframe) { + iframe = document.createElement("iframe"); + // 设置 iframe 的 frameBorder、width 和 height 为 0 iframe.frameBorder = iframe.width = iframe.height = 0; } - body.appendChild( iframe ); + // 将 iframe 添加到 body 中 + body.appendChild(iframe); - // Create a cacheable copy of the iframe document on first call. - // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML - // document to it; WebKit & Firefox won't allow reusing the iframe document. - if ( !iframeDoc || !iframe.createElement ) { - iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; - iframeDoc.write( ( jQuery.support.boxModel ? "" : "" ) + "" ); + // 在第一次调用时创建可缓存的 iframe 文档副本 + // IE 和 Opera 允许我们重用 iframeDoc 而无需重写假 HTML 文档;WebKit 和 Firefox 不允许重用 iframe 文档 + if (!iframeDoc ||!iframe.createElement) { + // 获取 iframe 的文档对象 + iframeDoc = (iframe.contentWindow || iframe.contentDocument).document; + // 向 iframe 文档中写入 HTML 内容 + iframeDoc.write((jQuery.support.boxModel? "" : "") + ""); + // 关闭 iframe 文档的写入操作 iframeDoc.close(); } - elem = iframeDoc.createElement( nodeName ); + // 在 iframe 文档中创建元素 + elem = iframeDoc.createElement(nodeName); - iframeDoc.body.appendChild( elem ); + // 将元素添加到 iframe 文档的 body 中 + iframeDoc.body.appendChild(elem); - display = jQuery.css( elem, "display" ); - body.removeChild( iframe ); + // 获取元素的 display 样式 + display = jQuery.css(elem, "display"); + // 从 body 中移除 iframe + body.removeChild(iframe); } - // Store the correct default display - elemdisplay[ nodeName ] = display; + // 存储正确的默认显示 + elemdisplay[nodeName] = display; } - return elemdisplay[ nodeName ]; + // 返回 elemdisplay 中存储的元素的默认显示 + return elemdisplay[nodeName]; } - + // 定义变量 getOffset,rtable 是一个正则表达式,用于匹配以 t 开头,后面跟 able、d 或 h 的字符串,不区分大小写 var getOffset, rtable = /^t(?:able|d|h)$/i, + // rroot 是一个正则表达式,用于匹配 body 或 html 字符串,不区分大小写 rroot = /^(?:body|html)$/i; - if ( "getBoundingClientRect" in document.documentElement ) { - getOffset = function( elem, doc, docElem, box ) { +// 检查 document.documentElement 是否有 getBoundingClientRect 方法 + if ("getBoundingClientRect" in document.documentElement) { + // 定义 getOffset 函数,接收 elem, doc, docElem, box 作为参数 + getOffset = function (elem, doc, docElem, box) { try { + // 尝试获取元素的边界矩形信息 box = elem.getBoundingClientRect(); - } catch(e) {} + } catch (e) {} - // Make sure we're not dealing with a disconnected DOM node - if ( !box || !jQuery.contains( docElem, elem ) ) { - return box ? { top: box.top, left: box.left } : { top: 0, left: 0 }; + // 确保元素不是一个断开连接的 DOM 节点 + if (!box ||!jQuery.contains(docElem, elem)) { + // 如果 box 存在则返回包含 top 和 left 的对象,否则返回 top 和 left 为 0 的对象 + return box? { top: box.top, left: box.left } : { top: 0, left: 0 }; } + // 获取 body 元素 var body = doc.body, - win = getWindow( doc ), - clientTop = docElem.clientTop || body.clientTop || 0, + // 获取窗口对象 + win = getWindow(doc), + // 获取 docElem 的 clientTop 或 body 的 clientTop,若都没有则为 0 + clientTop = docElem.clientTop || body.clientTop || 0, + // 获取 docElem 的 clientLeft 或 body 的 clientLeft,若都没有则为 0 clientLeft = docElem.clientLeft || body.clientLeft || 0, - scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, + // 获取页面垂直滚动距离 + scrollTop = win.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop, + // 获取页面水平滚动距离 scrollLeft = win.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft, - top = box.top + scrollTop - clientTop, + // 计算元素的 top 位置 + top = box.top + scrollTop - clientTop, + // 计算元素的 left 位置 left = box.left + scrollLeft - clientLeft; + // 返回包含元素最终计算得到的 top 和 left 位置的对象 return { top: top, left: left }; }; } else { - // 定义一个名为getOffset的函数,用于计算元素的偏移量 - getOffset = function( elem, doc, docElem ) { + // 定义 getOffset 函数,接收 elem, doc, docElem 作为参数 + getOffset = function (elem, doc, docElem) { var computedStyle, + // 获取元素的 offsetParent offsetParent = elem.offsetParent, + // 存储上一个 offsetParent prevOffsetParent = elem, + // 获取 body 元素 body = doc.body, + // 获取文档的默认视图 defaultView = doc.defaultView, - prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle, + // 获取元素的计算样式 + prevComputedStyle = defaultView? defaultView.getComputedStyle(elem, null) : elem.currentStyle, + // 获取元素的垂直偏移量 top = elem.offsetTop, + // 获取元素的水平偏移量 left = elem.offsetLeft; - while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) { - if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { + // 循环,从元素的父节点开始,直到 body 或 docElem 为止 + while ((elem = elem.parentNode) && elem!== body && elem!== docElem) { + // 如果 jQuery 支持 fixedPosition 且元素的位置是 fixed,则跳出循环 + if (jQuery.support.fixedPosition && prevComputedStyle.position === "fixed") { break; } - computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle; - top -= elem.scrollTop; + // 获取元素父节点的计算样式 + computedStyle = defaultView? defaultView.getComputedStyle(elem, null) : elem.currentStyle; + // 从元素的垂直偏移量中减去父节点的滚动距离 + top -= elem.scrollTop; + // 从元素的水平偏移量中减去父节点的滚动距离 left -= elem.scrollLeft; - if ( elem === offsetParent ) { - top += elem.offsetTop; + // 如果当前节点是元素的 offsetParent + if (elem === offsetParent) { + // 加上父节点的垂直偏移量 + top += elem.offsetTop; + // 加上父节点的水平偏移量 left += elem.offsetLeft; - if ( jQuery.support.doesNotAddBorder && !(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName)) ) { - top += parseFloat( computedStyle.borderTopWidth ) || 0; - left += parseFloat( computedStyle.borderLeftWidth ) || 0; + // 如果 jQuery 不添加边框且元素不是 table 或其单元格 + if (jQuery.support.doesNotAddBorder &&!(jQuery.support.doesAddBorderForTableAndCells && rtable.test(elem.nodeName))) { + // 加上父节点的上边框宽度 + top += parseFloat(computedStyle.borderTopWidth) || 0; + // 加上父节点的左边框宽度 + left += parseFloat(computedStyle.borderLeftWidth) || 0; } + // 更新 prevOffsetParent prevOffsetParent = offsetParent; + // 更新 offsetParent offsetParent = elem.offsetParent; } - if ( jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) { - top += parseFloat( computedStyle.borderTopWidth ) || 0; - left += parseFloat( computedStyle.borderLeftWidth ) || 0; + // 如果 jQuery 支持减去不可见溢出元素的边框且元素的 overflow 不是 visible + if (jQuery.support.subtractsBorderForOverflowNotVisible && computedStyle.overflow!== "visible") { + // 加上父节点的上边框宽度 + top += parseFloat(computedStyle.borderTopWidth) || 0; + // 加上父节点的左边框宽度 + left += parseFloat(computedStyle.borderLeftWidth) || 0; } + // 更新 prevComputedStyle prevComputedStyle = computedStyle; } - if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) { - top += body.offsetTop; + // 如果元素的位置是 relative 或 static + if (prevComputedStyle.position === "relative" || prevComputedStyle.position === "static") { + // 加上 body 的垂直偏移量 + top += body.offsetTop; + // 加上 body 的水平偏移量 left += body.offsetLeft; } - if ( jQuery.support.fixedPosition && prevComputedStyle.position === "fixed" ) { - top += Math.max( docElem.scrollTop, body.scrollTop ); - left += Math.max( docElem.scrollLeft, body.scrollLeft ); + // 如果 jQuery 支持 fixedPosition 且元素的位置是 fixed + if (jQuery.support.fixedPosition && prevComputedStyle.position === "fixed") { + // 加上 docElem 或 body 的垂直滚动距离 + top += Math.max(docElem.scrollTop, body.scrollTop); + // 加上 docElem 或 body 的水平滚动距离 + left += Math.max(docElem.scrollLeft, body.scrollLeft); } + // 返回包含元素最终计算得到的 top 和 left 位置的对象 return { top: top, left: left }; }; - }; + } // 重写jQuery的fn.offset方法,允许对jQuery对象进行偏移量设置或获取 jQuery.fn.offset = function( options ) { // 判断是否有传入参数,即是否要设置偏移量