2

My code is here. There are three position:zero(0,0),end(200,200),random(0,200).

A div is in the position random(0,200) at the beginning.

I want to :

step 1) set the div in the position zero(0,0). this step no animation

step 2) move it from position zero to position end by transition. this step has animation

Code like this does't work very well:

document.getElementById('x').className = 'pos_zero';    // set the div to the position zero(0,0)
move(); 
// in function move: 
// document.getElementById('x').className = ' trans'; 
// document.getElementById('x').className += ' pos_end' ;

It seems that transition starts too early, while css style(className = 'pos_zero') hasn't applied completely yet. It just directly moves from position random to position end. And what I really want is the animation to position end from position zero, not from random.

Code like this works:

document.getElementById('x').className = 'pos_zero';    // set the div to the position zero(0,0)    
setTimeout('move()',1);

This code do successfully by using a timeout function. This code sets the div in the position pos_zero first and then do transition asynchronously by a timeout function. And the timeout function seems not very professional.

So, I'm looking for a more professional solution.

By the way. I wonder. If there is any way to ensure the style is applied completely, like "Style.flush()" or something?

@Inerdial It does work!Many thanks.To force an update (to force an immediate, synchronous reflow or relayout), your javascript should read a property that's affected by the change, e.g. the location of someSpan and otherSpan.` The new code works without Timeout.

document.getElementById('x').className = 'pos_zero';
var tmp = document.getElementById('x').offsetTop; // read a property to force an update.
move(); 

Thank you guys all. And sorry for the confusing made by me.

hardPass
  • 19,033
  • 19
  • 40
  • 42
  • Using `setTimeout(move)` does what you want. Just use that. I don't understand what's the problem with this being "asynchronous", seeing as the `setTimeout` call is the last one in its function and you don't need its return value. – millimoose Jun 06 '12 at 12:12
  • 1
    It's confusing to create your own `$` function in the day and age of standardized JS frameworks. – mVChr Jun 06 '12 at 12:23
  • To Inerdial:You're right. But I think this "asynchronous" way seems odd, and makes me uncomfortable. And the `setTimeout` is not very convenient to use especially in a situation like being in an anonymous class or a prototype function. So I'm not into it very much, and looking for a better way. – hardPass Jun 06 '12 at 12:34
  • TO mVChr: That's true. the `$` here just returns `document.getElementById(id)`. You can see the whole code in `http://jsfiddle.net/VeJxD/`. As a new JavaScript coder, I'm not very into any JS frameworks like jQuery. No offense. Maybe I'm just not used to it. Perhaps I would change my mind soon. – hardPass Jun 06 '12 at 12:44
  • 1
    I don't really understand what's wrong with the animation. It seems to me it's working as expected. But if you need subtle perfection you should use `setInterval`. The difference between `setInterval` and `setTimeout` is that the first will execute the update asynchronously and will fire the next sequence after the first one has finished, but the last one will execute the code at the given timestamp which means it should happen the browser will fire the next update before the previous iteration hasn't finished yet. – Endre Simo Jun 06 '12 at 13:02
  • To esimov: Believe me, I know the difference between `setInterval` and `setTimeout`. And in this situation, I think `setTimeout` is better than `setInterval`. I suggest you look into my code carefully, and see the difference between two click-functions. – hardPass Jun 06 '12 at 14:33
  • @hardPass, I think mVChr's point was that if you're not using jQuery et al., just use `document.getElementById()` in full in SO code samples, so as to confuse the least people. – millimoose Jun 06 '12 at 15:46
  • @hardPass `setTimeout()` will accept an anonymous function / closure as a parameter, not just a string to eval. That should cover any use case you throw at it. As for being uncomfortable about relying on the DOM being redrawn between JS events, you could try what this answer (and others to the same question) mentions: http://stackoverflow.com/a/1397505/41655 (That said I can't understand why "stop processing the current event to redraw" is an odd pattern.) – millimoose Jun 06 '12 at 15:53
  • Why can't I re-vote for the comment again? I voted for the last comment of Inerdial. But with a repeated unconsciously click, the vote was undone. And now, I can't upvote it again. – hardPass Jun 08 '12 at 01:18

2 Answers2

2

Thanks to @Inerdial. It does work!. Actually this answer is coming from his comment.

To force an update (to force an immediate, synchronous reflow or relayout), your javascript should read a property that's affected by the change, e.g. the location of someSpan and otherSpan.` - stackoverflow.com/a/1397505/41655

The new code works without Timeout(jsfiddle.net/vd6V8):

document.getElementById('x').className = 'pos_zero';
var tmp = document.getElementById('x').offsetTop; // read a property to force an update.
move(); 

Thank you guys all. And sorry for the confusing made by me.

Community
  • 1
  • 1
hardPass
  • 19,033
  • 19
  • 40
  • 42
0

This is actually the only way, because between CSS changes the browser needs to "disengage" from the currently running code.

When you use setTimeout() the code exits, CSS gets applied and then your other code gets run. This yields the expected behaviour.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Actually I'm afraid this is not the only way to do that. Try this:stackoverflow.com/a/1397505/41655. I just got it from a comment. – hardPass Jun 07 '12 at 02:23
  • @hardPass Mozilla ain't Webkit ;-) but do let me know if you managed to solve it differently, I'll be interested to know. – Ja͢ck Jun 07 '12 at 02:43
  • @hardPass nifty! feel free to answer your own question :) – Ja͢ck Jun 07 '12 at 03:32