原生JS实现jQuery animate()函数:参数详解与核心逻辑

作者:像素漫游时间:2026-10-30 12:35:13浏览:490

本文介绍如何使用原生JavaScript实现类似jQuery的animate()动画函数。详细解析obj、json、interval、sp及回调函数fn等参数含义,重点阐述定时器隔离、多属性同步判断及数值取整等关键实现细节,并提供完整代码示例供参考。

背景与动机

经过一个月的实习,我对CSS和HTML的使用已较为熟练,近期开始深入JavaScript开发。今日尝试用原生JS编写了一个模拟jQuery animate()函数的动画模块,经测试性能表现良好。个人认为jQuery作为框架并非万能,其内部实现往往较为固化,例如animate()函数可选参数有限,有时难以满足特定的复杂动画需求。

代码中注释部分主要用于测试验证。编写过程并非一帆风顺,由于平时对JS底层细节关注较少,仅停留在宏观理解层面,但在实际实现动画逻辑时,细微的代码错误往往会导致调试困难。

函数参数详解

以下对该函数涉及的关键参数进行逐一解释:

• obj:目标操作对象。

• json:包含目标属性值的键值对对象,格式为{attr: 'value', attr: 'value'},指定需要执行动画的元素属性。

• interval:每次状态更新的间隔时间,即控制属性值变化的频率。

• sp:变化速率系数,用于实现缓冲效果,避免动画仅以匀速(sp为1时)进行,使运动更自然。

• fn:回调函数,动画执行完毕后触发的行为逻辑。

核心实现细节

代码逻辑相对简单,但有几个关键细节需要特别注意:

• 目标对象的属性无需预先声明,因此函数首行的clearInterval(obj.timer);不会引发错误,即使timer未定义也会安全执行。

• 必须为每个操作对象分配独立的定时器实例。若多个对象共用一个定时器,会导致运动状态相互干扰,出现明显的卡顿现象。

• 需关注json数据格式的处理。在遍历对象的动画属性时,通过判断icur != json[arr]来确认每个属性是否已到达目标值。flag变量用于防止因部分属性提前达到目标而误清定时器。每次遍历前将flag初始化为true,若发现任一属性未达标,则将flag置为false。只有当所有属性均达到目标值时,才清除定时器。

• speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);

该语句的作用是对属性变化值进行取整处理,因为除opacity外的CSS属性值通常不支持小数。

• 调用时需特别注意动画对象的作用域。在使用for循环时,应避免随意使用arr[i]形式,特别是在嵌套循环中,变量i的值可能已变为最大值,导致引用错误。

代码实现与调用

js


function animate(obj, json, interval, sp, fn) {
  clearInterval(obj.timer);
  //var k = 0;
  //var j = 0;
  function getStyle(obj, arr) {
    if(obj.currentStyle){
      return obj.currentStyle[arr];  //针对ie
    } else {
      return document.defaultView.getComputedStyle(obj, null)[arr]; 
    }
  }
  obj.timer = setInterval(function(){
    //j ++;
    var flag = true;
    for(var arr in json) {
      var icur = 0;
      //k++;
      if(arr == "opacity") {
        icur = Math.round(parseFloat(getStyle(obj, arr))*100);
      } else {
        icur = parseInt(getStyle(obj, arr));
      }
      var speed = (json[arr] - icur) * sp;
      speed = speed > 0 ? Math.ceil(speed): Math.floor(speed);
      if(icur != json[arr]){
        flag = false;
      } 
      if(arr == "opacity"){
        obj.style.filter = "alpha(opacity : '+(icur + speed)+' )";
        obj.style.opacity = (icur + speed)/100;
      }else {
        obj.style[arr] = icur + speed + "px";
      }
      //console.log(j + "," + arr +":"+ flag);
    }

    if(flag){
      clearInterval(obj.timer);
      //console.log(j + ":" + flag); 
      //console.log("k = " + k);
      //console.log("j = " + j);
      //console.log("DONE");
      if(fn){
        fn();
      }
    }
  },interval);
}

调用方式示例如下:


<script>
  var move = document.getElementById("move").getElementsByTagName("li");
  for(var i = 0; i < move.length; i ++){
    move[i].onmouseover = function(){
      var _this = this;
      animate(_this, {width: 500, height: 200},10, 0.01, function(){
        animate(_this, {width: 300, height: 200},10, 0.01);
      });

    }
  }

</script>

以上关于原生JS实现jQuery animate()动画效果的实例分享完毕,希望能为读者提供有价值的参考,欢迎支持本站更多内容。

作者最新文章