如何防止功能在特定时间(动画时)触发?

How to prevent function from trigger during a certain time (while animating)?

我有一个 UI,它有一个框,可以在单击时放大和缩小。它是动画的,当盒子关闭时,另一个动画应该是 运行。这两个事件都使用相同的函数和一些条件进行处理。

错误是当盒子打开时,我点击它,然后在缩小动画完成之前再次点击它,是放大回来但应该 运行 的动画缩小时触发。

如何确保只有在缩小完成后才能触发缩小后动画?这是代码(它是 angular 但在这里并不重要......):

animating = false; // I tried to use a flag, but it did not work

scope.toggleContextSlider = function() { // The click function
  if (scope.sliderClosed) { // The "avatar" is the "box"
    openSlider(scope.animtionDuration, scope.hearingContextAvatar); // The "avatar" is the "box"
  } else {
    closeSlider(scope.animtionDuration, scope.hearingContextAvatar);
  }
  scope.sliderClosed = !scope.sliderClosed;
}

动画函数:

function openSlider(animtionDuration, hearingContextAvatar) {
  // Animating stuff

  if (hearingContextAvatar && !animating) {
    closeStuff(animtionDuration, hearingContextAvatar)
  }
}

function closeSlider(animtionDuration, hearingContextAvatar) {
  // Animating stuff

  if (hearingContextAvatar && !animating) {
    openStuff(animtionDuration, hearingContextAvatar)
  }
}

function openStuff(animtionDuration, currentAvatar) { // This is the functions that is triggered with the double click
  animating = true;
  setTimeout(function(){
    // Animating stuff
    animating = false;
  }, animtionDuration);
}

function closeStuff(animtionDuration, currentAvatar) {
  animating = true;
  currentAvatar.removeClass('open')
  setTimeout(function(){
    // Animating stuff
    animating = false;
  }, animtionDuration);
}

好的,这里你想根据另一个触发一些事件。 为此,您可以使用 promise$q

您将能够使用 promises 的力量,通过解决您的 promises 轻松处理您的事件。

想法是使用两个标志,例如,这将告诉我们滑块是否打开。

我创建了一些动画函数来向您展示如何处理它。在这里,我用 for loop$timeout 函数模拟了一个事件。

控制器

(function(){

function Controller($scope, $q, $timeout) {

  $scope.slide = true;

  var closeResolved = true;

  var openResolved = false;

  $scope.show = false;

  $scope.processing = [];

  $scope.closing = [];

  $scope.toggle = function() {
    if ($scope.slide && closeResolved){
      event('open processing').then(function(data){
        $scope.show = data;
        //openResolved set to true
        openResolved = data;
        //closeResolved set to false
        closeResolved = !data;
      });

      $scope.slide = !$scope.slide;

    } else if (!$scope.slide && openResolved) {
      event('close processing').then(function(data){
        $scope.show = !data;
        //closeResolved set to true
        closeResolved = data;
        //openResolved set to false
        openResolved = !data;
      });

      $scope.slide = !$scope.slide;
    }

  }

  function event(processing){
    //Return promise, and resolve when loop is over
    return $q(function(resolve){
      for (var i = 0; i < 3; ++i){
        (function(i){
          $timeout(function(){
            //Update info processing array
            $scope.processing.push(processing);
            if (i == 2)
              resolve(true);
          }, 500 * i);
        })(i);
      }
    });
  }


}

angular
.module('app', [])
.controller('ctrl', Controller);

})();

HTML

  <body ng-app="app" ng-controller="ctrl">

    <button type="button" name="button" ng-click='toggle()'>Toggle</button>

    <h3 ng-if="show" style="color:green">OPEN</h3>
    <h3 ng-if="!show" style="color:red">CLOSE</h3>

    <ul>
      <li ng-repeat="item in processing track by $index">{{item}}</li>
    </ul>

 </body>

通过这个示例,您可以看到如果您向 toogle 按钮发送垃圾邮件,它不会引发多个事件。如果您在打开事件期间启动 close 事件,它将等待事件 open 完成。

可以看到Working Plunker