Javascript state

I call a javascript function that sets the iframe opacity to an unknown number of times in quick succession. Basically, it improves alpha from 0 to 100. here is the code

function setAlpha(value) { iframe.style.opacity = value * .01; iframe.style.filter = 'alpha(opacity =' + val + ')'; } 

My problem is that it works for the first time in ie (7), not firefox (3.02). in Firefox, I get a delay, and then a contentdocument appears with an opacity of 100. If I use a warning in it, then I assume that this is a race condition (although I thought that javascript was single-threaded) and that the setAlpha function is called before the last function completes. Any help would be greatly appreciated. I read β€œI avoid reporting race status in javascript,” but I think it matches somehow differently (plus I can't figure out how to apply this example to this).

+1
source share
4 answers

The problem is that most browsers do not redraw until there is a pause in javascript execution.

This can be solved using setTimeout, like others. However, I recommend using something like jQuery or any of the javascript libraries for animation. Running setTimeout 100 times is a bad idea, because the length of the animation will depend on the browser and the speed of the user computer. The correct way to animate is to indicate how long they should last and check the system time to determine how far the animation will go.

 function fadeIn(elem,animation_length) { var start = (new Date()).getTime(); var step = function() { window.setTimeout(function() { var pct = ((new Date()).getTime() - start)/animation_length; elem.style.opacity = Math.min(pct,1); if (pct < 1) step(); },20); }; step(); } 

[edit:] The code above is intended only to illustrate how to make animations based on the system clock instead of simple intervals. To create an animation, use the library. The code above will not work on IE, because IE uses "filter: opacity (xx)" instead of "opacity." Libraries will take care of this for you, as well as provide nice features such as completion events and the ability to cancel animations.

+5
source

Javascript does not work in multiple threads, so you are not safe from race conditions (ignoring the upcoming support for Worker threads in Safari and Firefox: D).

A simple question: how do you call setAlpha several times, firefox, safari and opera, all combine style sheet updates - for example. they will not redraw or even transcode style information while js is working, unless needed. Therefore, they will be drawn only if JS is completed.

So if you do

 while(...) setAlpha(...) 

they will not be updated, you will probably have to use setTimeout to launch several different calls to update the style.

An alternative would be to use a library such as jQuery, mootools, etc., which I vaguely recall, provide a simplified mechanism for these types of animations and transitions. As an added bonus, I believe that at least a few libraries will also use the webkit transition rules and css animations when they are available (like Safari, and I think the latest builds are firefox)

[edit: caveat: I really didn't use any of these libraries, I just read about what they should do. My sites do the same in trot as any other browser, because I could not develop my way out of the paper bag: D]

+1
source

Some browsers are smart enough to defer changes to the DOM until the call stack is empty.

This is usually a smart thing. For example, if you call a function that changes an element to yellow, and immediately call a function that returns the same element back to its original state, the browser should not waste time changing, as this should happen as quickly as being invisible to the user.

The setTimeout(func, 0) trick is usually used to force Javascript to delay the execution of func until the call stack is empty.

In code:

 function setAlpha(opacity){ some_element.style.opacity = opacity; } /** * This WON'T work, because the browsers won't bother reflecting the * changes to the element opacity until the call stack is empty, * which can't happen until fadeOut() returns (at the earliest) **/ function fadeOut(){ for (var i=0; i<10; i++){ setAlpha(0.1*i); } } /** * This works, because the call stack will be empty between calls * to setAlpha() **/ function fadeOut2(){ var opacity = 1; setTimeout(function setAlphaStep(){ setAlpha(opacity); if (opacity > 0){ setTimeout(setAlphaStep, 10); } opacity -= 0.1; }, 0); } 

It all boils down to being a great excuse to use one of the many javascript libraries that process this complex stuff for you.

Edit: here's a good article on the complex Javascript call stack

0
source

Are you using setTimeout or hard loop? If you only use a loop to call a function, switch to using setTimout.

Example:

  function setAlpha(value) { iframe.style.opacity = value * .01; iframe.style.filter = 'alpha(opacity =' + val + ')'; if(value < 100 ) { setTimeout(function () {setAlpha(value+1)},20); } } setAlpha(0); 

Because you see, this is not just javascript that has one stream. This is the whole damn browser. If your javascript falls into a narrow circle, you will hang the entire browser. Thus, the browser stops waiting for JavaScript to complete, and does not even have the ability to refresh the screen, while your code quickly changes some dom values.

0
source

Source: https://habr.com/ru/post/1401677/


All Articles