使用jQuery操作DOM时,代码不同步?

时间:2012-04-28 16:09:39

标签: javascript jquery dom css-transitions

我有这个功能:

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时,代码是不同步的?

4 个答案:

答案 0 :(得分:0)

这里可能发生的是,insertCSSTransitions()所做的样式更改在浏览器的释放控制之前无效,当它重新绘制时。

您只需要使用setTimeout(..., 1)来确保在浏览器处理transition样式后对元素宽度进行更改。

答案 1 :(得分:0)

使用回调?

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

答案 2 :(得分:0)

人们谈论异步行为,就像它是圣杯一样,但是当你想要它时,让JS同步往往是更困难的任务。 Frame.js(与其他流控制库如asnyc和flow.js一样)旨在解决此问题。在Frame中你会做:

var decreaseBar = function (barElement) {
    Frame(function(next)){
        insertCSSTransitions(barElement);
        next();
    });
    Frame(function(next)){
        $(barElement).find('.bar').width(0);
        next();
    });
    Frame.init();
}

答案 3 :(得分:0)

除非正在进行AJAX调用,否则JavaScript始终是同步的:When is JavaScript synchronous?

您的代码无效,因为您使用的CSS转换与JavaScript无法同步。 JavaScript是"添加"风格过渡到DOM,一旦完成,继续前进。

我不太确定您的功能的目的,因此很难找到更好的解决方案。总而言之,让JavaScript添加像您一样的硬编码样式通常是不好的做法。