#javascript #angularjs
#javascript #angularjs
Вопрос:
Мне пришлось добавить немного jQuery в конец кода, чтобы определить, когда заканчивается переход css. Есть ли способ заставить angular сделать это?
Способ, которым это работает, состоит в том, чтобы иметь объект, содержащий верхние и левые координаты, который вводится как встроенный стиль с помощью ng-style.
Некоторые из этих объектов хранятся в массиве. Всякий раз, когда обнаруживается событие перехода css3 end, вводится следующий объект.
Вот HTML с директивами Angular.
<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 ) amp;amp; (anime[playhead]) ) {
$('#readout').append('ended ' playhead ' ' JSON.stringify(anime[playhead]) '<br>');
saveTimeStamp = e.timeStamp;
$scope.mylist[2].inlinestyle = anime[playhead];
$scope.$apply();
playhead ;
}
});
}
]
);
Ответ №1:
Угловой способ заключается в определении директивы.
Я следил за этим сообщением в блоге: https://jonsuh.com/blog/detect-the-end-of-css-animations-and-transitions-with-javascript / и преобразовал этот код в угловую директиву следующим образом:
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()">