跳至主要內容

JavaScript 链式运动-动画

h7ml大约 1 分钟约 390 字

JavaScript 链式运动-动画

缓动运动框架

每次的步长 = (总路程 - 当前位置) / 运动系数(6-10)

function getStyle(el, attr) {
  return el.currentStyle ? el.currentStyle[attr] : getComputedStyle(el)[attr];
}

function bufferMove(el, obj, fn) {
  // fn就是回调函数
  clearInterval(el.timer);

  el.timer = setInterval(function () {
    var flag = true; // 判断是否所有属性都到达目标值,如果有一个属性没有到目标值,就将 flag 设置为 false。如果全部都到了目标值,那么 flag 就不会被改变为 false,就是初始 true
    for (var attr in obj) {
      // 判断 attr 是不是 opacity,是:采用一种获取办法,不是:采用之前的获取方法
      if (attr == 'opacity') {
        var cur = Math.round(getStyle(el, attr) * 100);
      } else {
        var cur = parseInt(getStyle(el, attr));
      }

      var step = (obj[attr] - cur) / 10;
      step = step > 0 ? Math.ceil(step) : Math.floor(step);

      // if(cur == obj[attr]){
      //  clearInterval(el.timer);
      // }

      if (cur != obj[attr]) {
        // 如果有一个当前值,不等于目标值,说明没有全部执行完成
        flag = false;
      }

      // 赋值时也分两种情况,一种是透明度,另一种是带有单位 px 的
      if (attr == 'opacity') {
        el.style.opacity = (cur + step) / 100;
        el.style.filter = 'alpha(opacity=' + (cur + step) + ')';
      } else {
        el.style[attr] = cur + step + 'px';
      }
    }

    if (flag) {
      // 如果 flag 为假,说明没有全部属性达到目标值,那么不清除定时器,如果 flag 为 true 说明全部属性都达到了目标值,就清除定时器
      clearInterval(el.timer);

      // fn && fn();
      // 回调函数的 this 指向 window,当该运动框架适用于元素集合时,this 执行导致报错

      // if(fn) fn();
      // 改 call 就是修改函数的调用时的 this 指向
      if (fn) fn.call(el);
    }
  }, 20);
}