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



我有这个功能:

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 像你一样添加硬编码样式通常是不好的做法。

相关内容

  • 没有找到相关文章

最新更新