【问题标题】:How to prevent function from trigger during a certain time (while animating)?如何防止功能在特定时间(动画时)触发?
【发布时间】:2015-08-13 21:06:16
【问题描述】:

我有一个用户界面,其中有一个在点击时会放大和缩小的框。它是动画的,当盒子关闭时,应该运行另一个动画。这两个事件都使用相同的函数和某些条件来处理。

错误是,当框打开时,我单击它,然后在缩小动画完成之前再次单击它,被放大但只有在缩小时才应该运行的动画,被触发。

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

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);
}

【问题讨论】:

  • 永远不会调用 openStuff() 和 closeStuff() 函数,因此您的布尔标志永远不会从 false 更改其值。
  • @HankScorpio 他们是,我更新了名字。
  • @ilyo 你在我的解决方案中找到你想要的了吗?

标签: javascript angularjs user-interface animation queue


【解决方案1】:

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

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

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

我创建了一些动画函数来向您展示如何处理它。在这里,我使用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>

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

你可以看到Working Plunker

【讨论】:

    猜你喜欢
    • 2011-06-18
    • 2014-02-19
    • 1970-01-01
    • 2018-01-19
    • 2019-09-11
    • 1970-01-01
    • 2013-12-10
    • 2021-12-20
    • 2014-12-02
    相关资源
    最近更新 更多