简体   繁体   中英

The code is not synchronized when manipulating the DOM with jQuery?

I have this function:

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

The insertCSSTransitions(barElement) function, do this:

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

What happens is: the $(barElement).find('.bar').width(0); line set the width to 0 before the style of cssTransitions work.

Because, if I modify decreaseBar function to that, it works:

var decreaseBar = function (barElement) {
   insertCSSTransitions(barElement);

   // set a delay of 1 second before set to 0
   setTimeout(function() {
      $(barElement).find('.bar').width(0);
   }, 1000)
}

The code is not synchronized when manipulating the DOM with jQuery?

What is probably happening here, is the style changes made by insertCSSTransitions() are not effective until your release control of the browser, when it does repaint.

You really just need to use setTimeout(..., 1) to ensure that change to the element width are done after the browser has processed the transition style.

Use a callback ?

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

That's just a simple example of a callback, it does not wait for CSS transitions to take place, and there shoud be a simple typeof check to see if the callback is a function if it's intended for something else aswell.

EDIT:

As Pointy points out, the callback does'nt do much, other than show how it's done etc. binding the callback to the transition end is probably the way to go, but that property has a bunch of prefixes, solved here with some simple browser detection, but there are libraries out there for checking actual support in the browser.

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

People talk about asynchronous behavior like it is the holy grail, but getting JS to be synchronous when you want it to can often be the more difficult task. Frame.js (like other flow control libraries such as asnyc and flow.js) was designed to solve this problem. In Frame you would do:

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

JavaScript is always synchronous unless an AJAX call is being made: When is JavaScript synchronous? .

Your code is not working because you are using a CSS transition which would not be synchronous with JavaScript. JavaScript is "adding" the style transitions to the DOM and once complete, moving on.

I'm not quite sure of the purpose of your functions, so its difficult to come up with a better solution. All-in-all, it is usually bad practice to have JavaScript add hard coded styles like you are doing.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM