jQuery addClass method chaining to perform CSS transitions

前端 未结 4 583
独厮守ぢ
独厮守ぢ 2021-01-16 09:06

What I would like to do (broke):

4条回答
  •  温柔的废话
    2021-01-16 09:32

    Good question! This behaviour definitely seems weird at first. It's also a little tricky to explain this clearly, but to start, understand the following:

    1) Javascript functions execute atomically

    In JS, functions always run from beginning to end without any possibility of some other operation occurring midway through. This is the same as saying that JS is a single-threaded language.

    2) The browser can't interrupt javascript either

    Not only is JS code prevented from running midway through a function, but the browser tab in which the code is running will also not interject! This means that (nearly) EVERYTHING on a webpage is halted (repaints, animations, stylesheet application, etc) when a JS function is running. If you want to test this, you can try running while (true) { var i = 'yo'; } in the console. (Warning: this will make you sad)

    3) State inside of JS functions is invisible to browsers

    Because the browser can't interrupt in the middle of a JS function it means the browser can never know any state that occurs mid-way through said function. The browser can only act based off of the state that remains once a function finishes. Not clear? To illustrate:

    var someGlobalValue = null;
    
    function lol() {
        someGlobalValue = 'hi';
        someGlobalValue = 'hello';
        someGlobalValue = 'ok';
    }
    

    When the function lol is run, someGlobalValue assumes multiple values, but the browser will only ever be aware of the last one, because it would have to interject midway through in order to see the others (which it can't do!)

    4) CSS State inside of JS functions is similarly invisible to browsers

    The same applies to css state! (And now you may see that I am, in fact, beginning to answer your question).

    If you call the following function:

    function lol() {
        $('.thing').css('left', '10px');
        $('.thing').css('left', '30px');
    }
    

    The browser will never apply the left: 10px value because it takes no actions midway through a function! Only the results of a function, one it is complete, can be worked with by the browser.

    Answering your questions!!

    fiddle 1

    The left_more class is added immediately after the left class - the browser never sees the left class, and applies css styling after the function ends - applying the left_more class, but since no initial left value was present there is no animation. (The css cascades; while both classes are present, left_more fully overwrites left)

    fiddle 2

    Same issue - the left class is overwritten before the browser can process it

    fiddle 3

    This works because the value is set with a call to css, and then is NOT overwritten because addClass is used to set where the value should animate to. The console.log is irrelevant - all that is important is the css function call. Once that function completes, there are 2 pieces of information, 1 being the css value, the other being the class value. This contrasts the other example where there is only one piece of information left after the function runs: the class value.

    If you wanted to work with only classes, and still get the transition going, the flow would have to look like this:

    1) Add left class 2) Exit function, which allows the browser to view the state 3) Add left_more class

    Sry for the essay lol. But I think this needed a long explanation because of the subtlety of the issue.

提交回复
热议问题