angular如何在ng样式触发转换的css转换结束时监听事件?

How can angular listen event for css transition end where ng-style triggers the transition

本文关键字:转换 css 结束 监听 事件 ng 样式 angular      更新时间:2023-09-26

我必须在代码末尾添加一些jQuery来检测css过渡何时结束。有办法让angular做这个吗?

working jsfield is here

它的工作方式是有一个对象,其中包含顶部和左侧的坐标被注入作为内联样式的ng-style。

其中一些对象保存在数组中。每当检测到css3结束转换事件时,就会注入下一个对象。

下面是带有Angular指令的HTML。

 <div id="mycontainer" ng-controller="mycontroller">
   <div ng-repeat="item in mylist" id="item{{item.key}}" class="item" ng-style="myproperties({{item.key}})">{{item.value}}</div>
 </div>
 <div id="readout"></div>

这里是Javascript/Angular,你会看到jQuery,很明显是在末尾添加的。

var myapp = angular.module('myapp', []);
myapp.controller(
  'mycontroller', 
  [
    '$scope',
    '$log',
    function($scope, $log) {
      // define the items
      $scope.mylist = [];
      for (var i = 0; i < 6; i++) {
        $scope.mylist[i] = {'key':i, 'value':i, 'inlinestyle':{'top':'60px','left': (i*60)+'px'}};
      }
      $scope.myproperties = function(arg) {
              return $scope.mylist[arg].inlinestyle;
      };
      /*  test animatimng item number 2 */
      var anime = [
        {'top':'120px','left':'50px', 'background':'#ccc'},
        {'top':'150px','left':'120px', 'background':'#3cc'},
        {'top':'60px','left':'120px', 'background':'#c3c'},
        {'top':'120px','left':'130px', 'background':'#cc3'},
        {'top':'150px','left':'160px', 'background':'#fff'}
      ];
      var playhead = 0;
      var saveTimeStamp = 0;
      // adter a second, start the anime sequence
      setTimeout(function(){
        $scope.mylist[2].inlinestyle = anime[0];              
        $scope.$apply();
        playhead++;       
      }, 1000);
      //listener for end of transition
      // aaaah ...  now I have to use jQuery
      $('html').on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(e){
        if (( e.timeStamp != saveTimeStamp ) && (anime[playhead])  )  {
          $('#readout').append('ended '+playhead+' '+JSON.stringify(anime[playhead])+'<br>');
          saveTimeStamp = e.timeStamp;            
          $scope.mylist[2].inlinestyle = anime[playhead];              
          $scope.$apply();
          playhead++;
        }                
      });
    }
  ]
);

Angular的方式是定义一个指令。

我关注了这个博客:https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript/然后把这些代码转换成这样的angular指令:

 myapp.directive('myTransitionEnd', [
           '$parse',
 function ( $parse  ) {
    var transitions = {
        "transition"      : "transitionend",
        "OTransition"     : "oTransitionEnd",
        "MozTransition"   : "transitionend",
        "WebkitTransition": "webkitTransitionEnd"
    };
    var whichTransitionEvent = function () {
        var t,
            el = document.createElement("fakeelement");
        for (t in transitions) {
            if (el.style[t] !== undefined){
                return transitions[t];
            }
        }
    };
    var transitionEvent = whichTransitionEvent();
    return {
        'restrict': 'A',
        'link': function (scope, element, attrs) {
            var expr = attrs['myTransitionEnd'];
            var fn = $parse(expr);
            element.bind(transitionEvent, function (evt) {
                console.log('got a css transition event', evt);
                var phase = scope.$root.$$phase;
                if (phase === '$apply' || phase === '$digest') {
                    fn();
                } else {
                    scope.$apply(fn);
                }
            });
        },
    };
 }]);

然后,像这样修改你的HTML:

<div id="mycontainer" ng-controller="mycontroller" my-transition-end="callSomeScopeFunctionYouDefined()">