因此,当用户单击某些元素时,我正在使用YUI在我的应用程序中添加一些动画。但是,我遇到了一个常见的问题,很容易通过一些不良的编码修复,但我正在寻找一个更不容易出错的更优雅的解决方案。
通常,当用户点击某些内容时,DOM元素会被动画化(使用Y.Anim),我订阅该动画的'end'事件,以便在动画完成后从文档中删除该元素。非常标准的东西。
但是,当用户决定垃圾邮件单击触发此事件的元素时,就会出现问题。如果在动画结束时将从DOM中删除该元素,并且用户触发在同一元素上触发另一个动画的事件处理程序,则此第二个动画将最终导致YUI吐出真正令人讨厌的错误,因为它是节点动画突然从文件中消失了。我发现的最快的解决方案是设置一些模块/类级别的布尔状态,如'this.postAnimating'或其他东西,并在触发动画的事件处理程序中,检查是否设置为true,如果所以,不要做任何事情。在动画的“结束”处理程序中,将此状态设置为false。
由于很多原因,这个解决方案真的非常不理想。另一种可能的解决方案是在动画持续时间内分离事件处理程序,并在动画完成后重新附加它。这肯定好一点,但我仍然不喜欢不得不做额外的簿记,如果忘记这样做会导致难以理解的YUI错误,我很容易忘记做。
什么是一种优雅而强大的方法来解决这个问题而不会破坏一个包含多个状态的数千行Javascript文件?
以下是一些描述问题的示例代码及其解决方案。
var popupShowing = false,
someElement = Y.one('...');
someElement.on("click", showPopUp)
var showPopup = function(e) {
if(!popupShowing) {
popupShowing = true;
var a = new Y.Anim({
node: someElement,
duration: 0.2,
...
});
a.on('end', function() {
someElement.remove(true);
popupShowing = false;
});
a.run();
}
}
因此,如果用户多次点击“someElement”,则只会触发一个动画。如果我没有使用popupShowing作为一个警卫,如果用户足够快地点击,同一节点上的许多动画会被触发,但随后的那些会出错,因为在第一次完成时删除了someElement。
答案 0 :(得分:1)
查看Transition API。它更简洁,可以很好地完成您想要的开箱即用。
someElement.transition({ opacity: 0, duration: 0.2 }, function () { this.remove(); });
// OR
someElement.on('click', function () { this.hide(true, { duration: 0.2 }); });
// OR
someElement.on('click', someElement.hide);
就个人而言,我没有使用Anim,因为在3.2.0中添加了Transition。 Transition使用受支持的CSS3(使用硬件加速),然后回退到旧浏览器的JS计时器。 http://developer.yahoo.com/yui/3/examples/transition/transition-view.html
答案 1 :(得分:0)
编辑:按流行需求,YUI方式:
myAnim.get('running')
告诉您动画是否正在运行。要使用它,您可能必须重新调整事件的方式,以便动画在正确的范围内,例如:
YUI().use('anim', function (Y) {
var someElement = Y.one('...');
var a = new Y.Anim({
node: someElement,
duration: 0.2,
...
});
a.on('end', function() {
someElement.remove(true);
});
someElement.on('click', function() {
if (!a.get('running')) {
a.run();
}
});
});
以前我说过:我个人喜欢jQuery处理这个问题的方式。在jQuery中,每个元素都有一个动画函数队列。在动画期间,“进行中”哨兵在动画期间被推到前面,所以任何不想踩动画片的东西都会在队列前面偷看“进行中”并决定从那里做什么,例如什么都不做,排队,抢占当前的动画等等。
我不太了解YUI告诉你如何实现这个,但是我发现它是一个非常优雅的解决方案。
答案 2 :(得分:0)