0

On vanilla-js.com they show an example of a fade out.

var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();

I tried this example but it didn't work (it doesn't completly fade out: http://jsfiddle.net/qvKW7/2/

Also i didn't quite understand what this exactly does: (s.opacity-=.1)<0 .. what does the < sign do?

I really liked this code snippet. Does someone know more resources of jquery stuff done in javascript instead of the unminified jquery...?

Thanks

user1081577
  • 469
  • 2
  • 8
  • 25
  • What do you mean by "doesn't completely fade"? It works fine for me. What browser are you using? – Bergi Jul 15 '13 at 13:43
  • @bergi it doesn't completly fadeout in chrome version 28.0.1500.71 m. It stops at opacity: 0.10000000000000014 – user1081577 Jul 15 '13 at 14:05

5 Answers5

6

Explaining the function:

(//this and the bottom closure executes the function inside.
 function fade(){//the function is named fade
  (s.opacity-=.1)//sets the opacity to current opacity-0.1, 
   <0?  // if the opacity - 0.1 is smaller than 0 ('<' = smaller then)
  s.display="none" // set display to none
   : // else
  setTimeout(fade,40) // set a timer of 40 ms and execute the function fade again
 }
)();

this is a nice javascript way to play around with a style but:

1.it's written enterly in javascript

with css3 you have such animations without the need of javascript and the cool part of it is that the browser (with some tricks) uses hw gpu acceleration and so the animation is very fluid. if you need this type of animation in very old browsers with no css3 support then yeah u need this but also some polyfills and the use of ie filter to set the opacity.

2.it sets the display to none

setting an element to display:none is not a good way to do it if u plan to reuse the element. becaue if u want to show it again it has to redraw it.

3.it uses a setTimeout

setTimeout is as bad choice always.

Now to the answer:

i don't know exactly what do you wanna achieve but

look at this example (this works in chrome and safari ,android and ios) but can be changed towork on most browsers.

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>example</title>
<style>
div{
 background-color:#fc0;
 -webkit-transition:opacity 1500ms ease;
 opacity:1;
}
div.hide{
 opacity:0;
}
</style>
<script>
var changeclass=function(){
 this.classList.add('hide');
}
window.onload=function(){
 var firstDiv=document.getElementsByTagName('div')[0];
 firstDiv.addEventListener('mouseover',changeclass,false);
}
</script>
</head>
<body>
<div>Hello</div>
</body>
</html>

i create a css class for my element. div

inside this div i set the css3 property transition toanimate the opacity with a easing and 1500 milliseconds

and an extra class to hide it div.hide

this contains only the opacity set to 0.

now in my example i hide the element on mouseover.

so when the my div element has loaded (window.onload) i add an eventhandler (mouseover)

to change the class of my div element, which i called changeclass.

cocco
  • 16,442
  • 7
  • 62
  • 77
  • Thanks for your answer, Do you also know why it doesn't completly fade out in chrome's latest version? In firefox it works fine... – user1081577 Jul 15 '13 at 14:18
  • i think it's because putting a setter (s.display="none") in a shorthand function is wrong.so prolly new chrome creates an error.. but yeah there are no errors in console. – cocco Jul 15 '13 at 14:22
4

What browser are you testing in? It works for me in Firefox 21, but the < in there is part of the ternary statement. The code you have posted is the same as:

var s = document.getElementById('thing').style; // s holds the style of 'thing'
s.opacity = 1; // sets the opacity to be fully opaque
(function fade() { // function will automatically execute itself
    if ((s.opacity-=.1) < 0) // decrements the opacity by .1 AND checks if the opacity is less than 0
        s.display="none"; // if the opacity has dropped below 0, hide the element altogether
    else
        setTimeout(fade,40);  // otherwise, run this function again in 40ms
})();

Also, maybe try (s.opacity-=.1) < .1

1

You could try decrementing a variable and setting the opacity to that value:

var s = document.getElementById('thing').style;
var o = 1;
(function fade(){
    s.opacity = o-=0.1;
    o < 0 ? s.display="none" : setTimeout(fade,40);
})();
Mike
  • 312
  • 6
  • 18
1

(s.opacity-=.1)<0 .. what does the < sign do?

It's the common smaller-than comparison. The author wants to check when the opacity reaches zero. Yet, floating point math is inprecise, so ==0 won't do it.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thanks, I know it's the smaller than comparison but i'm confused in how it's used. Is it comparing the current s.opacity - .1 with 0? Does it mean the same as: `if (s.opacity - .1 < 0) { 0 : etc ? etc }` – user1081577 Jul 15 '13 at 13:56
  • 1
    @user1081577 an important part to remember is that (given `a=1;b=2;c=3`) `a = b = c` is completely valid in javascript, and so is `a = b -= c`. Now the question is, what is `a` in this example? It's quite simple actually, this can be written as `b -= c; a = b` and you'd achieve the same thing. So basically, the script is doing two operations at once. It's decreasing the opacity, and using the result of the decrease to check against 0. This check returns a bool that is used in a ternary expression (`cond ? ifTrue : ifFalse`). – Alxandr Jul 15 '13 at 14:16
0

This is probably late but I didn't find the answer to the original question here and no one seems to have addressed it anywhere else.

When fading out, it is safer to use 0.1 as the minimum value in the conditional statement like this:

(s.opacity-=.1) < .1 

because

(s.opacity-=.1)

should actually evaluate to zero at the end of the animation and not a negative value (which is required for this to work:

(s.opacity-=.1) < 0 // s.opacity cannot be < 0... 

You could also use:

(s.opacity-=.1) <= 0 

but I prefer:

(s.opacity-=.1) < .1

I also prefer to replace

s.display="none" 

with

s.opacity=0

Final code:

// fade out...
// This way you do not end up with an incomplete fade...

var s = document.getElementById('thing').style;
s.opacity = 1;

(function fade(){
  (s.opacity-=.1)<0.1 ? s.opacity=0 : setTimeout(fade,40) })();

When fading in, use 0.9 for the maximum opacity value like this:

(s.opacity+=.1) > .9 

Because

(s.opacity+=.1) 

can not evaluate to a value greater than 1. As before you can also do this:

(s.opacity+=.1) >= 1 // but I prefer > .9 ...

And finally set s.opacity to 1 at the end of the animation.

// fade in...

var s = document.getElementById('thing').style;
s.opacity = 0;

(function fade(){ (s.opacity+=.1) > 0.9 ? s.opacity=1 : setTimeout(fade,40) })();
katalin_2003
  • 787
  • 1
  • 16
  • 30
Yega
  • 356
  • 5
  • 10