导读:本期聚焦于冷风创作的《如何通过jQuery.speed()解析动画参数并自定义缓动函数(Easing)》,敬请观看详情。jQuery 的动画入口方法最终都会调用内部工具函数 speed 来统一处理参数。这个函数会先判断传入的第一个参数是否对象,如果是对象则直接读取 duration、easing、complete 等属性;如果不是对象,则把数值或字符串的速度值赋给 duration,并把缓动名称和回调函数依次后移。它还会处理 fast、slow 等预设字符串,最终生成一个包含 duration、easing、queue、complete 等字段的规范对象。理解了 speed 的参数解析逻辑,就能明白为什么 animate 支持多种写法,也就能知道自定义缓动函数只需要向 jQuery.easing 对象添加一个以进度为入参、返回位移比例的方法即可。文章将结合源码片段与实例,说明如何注册并使用自定义缓动函数,以及缓动函数在动画循环中的调用时机和优化建议。

jQuery 的 animate 方法支持多种参数组合,比如可以把速度、缓动名称、回调函数分开传,也可以打包成一个对象。这种灵活性依赖于内部一个核心工具函数,它就是 speed。speed 函数承担了参数标准化的工作,把开发者随性书写的参数解析成动画引擎可以消费的规范结构。要自定义缓动函数,先得理解这个解析过程,否则容易在传参顺序或选项对象上踩坑。

如何通过jQuery.speed()解析动画参数并自定义缓动函数(Easing)

jQuery.speed() 的参数解析逻辑

speed 函数位于 jQuery 源码内部,主要负责处理 animate 方法传入的速度、缓动名称和完成回调。它的核心任务是将三种完全不同的调用形式统一成一个对象。当第一个参数是对象时,会直接使用 jQuery.extend 复制对象属性;当第一个参数是数值或字符串时,才进入分派逻辑,把后续参数依次视为 easing 和 complete。整个过程看似简单,但衍生出不少边界情况。

下面是一段简化后的 speed 函数实现,可以帮助理解它的分派与默认值填充逻辑。

function speed(speed, easing, fn) {
  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
  };

  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;

  if (opt.queue == null || opt.queue === true) {
    opt.queue = 'fx';
  }

  opt.old = opt.complete;
  opt.complete = function() {
    if (jQuery.isFunction(opt.old)) {
      opt.old.call(this);
    }
    if (opt.queue) {
      jQuery.dequeue(this, opt.queue);
    }
  };

  return opt;
}

代码中 opt.duration 这一行处理了三种情况:如果 jQuery.fx.off 为 true 则直接将持续时间设为 0,用于关闭动画;如果传入的是数字则直接使用;如果是 fast 或 slow 字符串,则去 jQuery.fx.speeds 映射中查找,找不到就用默认值 400 毫秒。而 complete 回调被包装了一层,目的是在动画结束后自动出队,保证队列中的下一个动画能继续执行。

实际使用中,可以通过 jQuery.speed 直接查看解析结果,虽然这不是公开 API,但方便调试参数传递。

// 常见写法
var opt1 = jQuery.speed(800, 'swing', function() {
  console.log('动画完成');
});
console.log(opt1);
// 输出: { duration: 800, easing: 'swing', queue: 'fx', complete: [Function], ... }

var opt2 = jQuery.speed({
  duration: 600,
  easing: 'linear',
  complete: function() {}
});
console.log(opt2.duration); // 600

注册自定义缓动函数的正确姿势

jQuery 的缓动函数统一挂在 jQuery.easing 对象上。内置只有两个:线性函数 linear 直接返回进度,摆动函数 swing 使用余弦变换让动画首尾慢中间快。自定义缓动非常直接,就是往 jQuery.easing 对象上添加一个新的方法。这个方法的入参是 0 到 1 的进度值,返回值表示对应时间点的位移比例,通常也落在 0 到 1 之间,但某些弹性或过冲效果会短暂超过边界。

以下示例注册了一个三次缓入缓出函数,它在前半段加速、后半段减速,视觉效果比 swing 更柔和。

// 注册自定义缓动函数
jQuery.easing.easeInOutCubic = function (p) {
  if (p < 0.5) {
    return 4 * p * p * p;
  }
  return 1 - Math.pow(-2 * p + 2, 3) / 2;
};

// 使用自定义缓动
$('#box').animate({ left: 300 }, 1000, 'easeInOutCubic', function() {
  console.log('移动完成');
});

缓动函数内部应当只依赖入参 p 做数学计算,不要使用 this,也不要读取或修改外部动画状态。如果需要在动画结束时执行逻辑,应该通过 complete 回调,而不是在缓动函数里做额外操作。另外要注意命名冲突,不要覆盖内置的 linear 和 swing,否则会影响所有使用默认缓动的动画。

除了常见的三次曲线,还可以实现带回弹效果的 easeOutBack,它会让元素在终点前稍微超过目标位置再回弹,常用于强调交互反馈。

jQuery.easing.easeOutBack = function (p) {
  var c1 = 1.70158;
  var c3 = c1 + 1;
  return 1 + c3 * Math.pow(p - 1, 3) + c1 * Math.pow(p - 1, 2);
};

$('#box').animate({
  left: 300
}, {
  duration: 800,
  easing: 'easeOutBack',
  complete: function() {
    console.log('带过冲效果的动画结束');
  }
});

缓动函数的调用时机与动画性能优化

jQuery 动画每执行一帧,都会根据已过去的时间和总持续时间计算出一个原始进度 p,然后调用对应的缓动函数得到 eased 值,再用这个 eased 值去插值计算当前属性数值。缓动函数每秒被调用几十次,因此它本身的计算量会直接反映到动画流畅度上。一个函数里多出几次 Math.pow 通常没有大问题,但如果在缓动函数内读写 DOM、强制触发重排,或者创建大量临时对象,就可能造成明显卡顿。

下面模拟了 jQuery 动画循环中缓动函数被调用的过程,便于理解其执行频率与位置。

// jQuery 动画循环中的简化调用逻辑
function tick() {
  var currentTime = Date.now();
  var elapsed = currentTime - startTime;
  var p = Math.min(elapsed / duration, 1);
  var eased = jQuery.easing[easingName](p);
  var currentValue = startValue + (endValue - startValue) * eased;
  element.style.left = currentValue + 'px';
  if (p < 1) {
    requestAnimationFrame(tick);
  }
}

优化自定义缓动函数时,首先应当将函数引用在动画开始前取出,避免每帧用字符串去 jQuery.easing 对象中查找。其次,不要在缓动函数内部声明新的数组或对象,尽量复用外部变量。如果多个元素使用同一条缓动曲线,可以让它们共享同一个函数引用,减少内存分配。对于单纯的线性或摆动动画,直接使用内置函数即可,不必为了自定义而自定义。

理解 speed 的解析机制和缓动函数的运行原理后,就能在 jQuery 动画中灵活定制曲线,同时避免参数传递错误和性能陷阱。自定义缓动函数本质上就是给动画引擎提供一个纯数学映射,只要保证输入输出稳定、计算轻量,它就能配合动画队列持续稳定地工作。

jQuery.speed缓动函数Easing修改时间:2026-09-23 12:53:53

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0923/60905.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。