我有这个功能:
var decreaseBar = function (barElement) {
insertCSSTransitions(barElement);
$(barElement).find('.bar').width(0);
}
insertCSSTransitions(barElement)
函数,执行以下操作:
var insertCSSTransitions = function (barElement) {
var timeBar = settings.timeBar;
$(barElement).find('.bar').attr('style', 'transition:width ' + timeBar + 's; -moz-transition:width ' + timeBar + 's; -webkit-transition:width ' + timeBar + 's; -o-transition:width ' + timeBar + 's');
}
发生的情况是:在 cssTransitions 的样式工作之前,$(barElement).find('.bar').width(0);
行将width
设置为 0。
因为,如果我修改decreaseBar
函数,它可以工作:
var decreaseBar = function (barElement) {
insertCSSTransitions(barElement);
// set a delay of 1 second before set to 0
setTimeout(function() {
$(barElement).find('.bar').width(0);
}, 1000)
}
使用 jQuery 操作 DOM 时代码不同步?
可能发生的情况是,insertCSSTransitions()
所做的样式更改在您对浏览器的发布控制之前无效,当它重新绘制时。
您实际上只需要使用 setTimeout(..., 1)
来确保在浏览器处理transition
样式后完成对元素宽度的更改。
人们谈论异步行为就像它是圣杯一样,但是在你想要的时候让JS同步通常是更困难的任务。Frame.js(像其他流控制库,如asnyc和flow.js)就是为了解决这个问题而设计的。在框架中,您将执行以下操作:
var decreaseBar = function (barElement) {
Frame(function(next)){
insertCSSTransitions(barElement);
next();
});
Frame(function(next)){
$(barElement).find('.bar').width(0);
next();
});
Frame.init();
}
使用回调?
var decreaseBar = function (barElement) {
insertCSSTransitions(barElement, function() {
$(barElement).find('.bar').width(0);
});
}
var insertCSSTransitions = function (barElement, callback) {
var timeBar = settings.timeBar;
$(barElement).find('.bar').attr('style', 'transition:width ' + timeBar + 's; -moz-transition:width ' + timeBar + 's; -webkit-transition:width ' + timeBar + 's; -o-transition:width ' + timeBar + 's');
setTimeout(function() {callback.call();}, timebar*1000);
}
这只是一个简单的回调示例,它不会等待 CSS 转换发生,并且应该有一个简单的检查类型来查看回调是否是一个函数,如果它也用于其他东西。
编辑:
正如 Pointy 指出的那样,回调除了显示它是如何完成的等之外,并没有做太多事情。将回调绑定到过渡端可能是要走的路,但该属性有一堆前缀,在这里通过一些简单的浏览器检测来解决,但是有一些库可以检查浏览器中的实际支持。
var insertCSSTransitions = function (barElement, callback) {
var timeBar = settings.timeBar,
transitionEnd = "TransitionEnd";
if ($.browser.webkit) {transitionEnd = "webkitTransitionEnd";}
else if ($.browser.mozilla) {transitionEnd = "transitionend";}
else if ($.browser.opera) {transitionEnd = "oTransitionEnd"; }
$(barElement).find('.bar')
.attr('style', 'transition:width ' + timeBar + 's; -moz-transition:width ' + timeBar + 's; -webkit-transition:width ' + timeBar + 's; -o-transition:width ' + timeBar + 's');
.on(transitionEnd, function() {
callback.call();
});
}
JavaScript 始终是同步的,除非正在进行 AJAX 调用:JavaScript 何时同步?。
您的代码不起作用,因为您正在使用与 JavaScript 不同步的 CSS 过渡。JavaScript 正在将样式转换"添加"到 DOM 中,一旦完成,继续前进。
我不太确定您的函数的目的,因此很难提出更好的解决方案。总而言之,让 JavaScript 像你一样添加硬编码样式通常是不好的做法。