Element Fade Out - Compatibility Coding

I’m very new to javascript and web development. I’m looking to implement a fade in / fade out mechanism in a site I’m working on. I don’t know how to make it accessible for more browsers. Here’s a little test version:

<h1 id="myh1" onclick="fadeout();">Click Me</h1>
<script type="text/javascript">

var fadeobject = document.getElementById('myh1');
var x=10;
var mytimer="";

function fadeout(){ mytimer = window.setInterval("dofade()",50); }

function dofade(){

	if(x>0){ 
	
	var y=x/10;
	
	fadeobject.style.opacity=y; 
	x-=1; 
	
	}else{ 
	window.clearInterval(mytimer);
	
	fadeobject.style.visibility='hidden';
	}
}


</script>

This works on my ie (9), ff (8) and chrome (16.0.9…). But I gather that opacity will not work on other/older browsers. Plus I need to cater for those with javascript off.

How can i edit it to fade on other widely used browsers that don’t support ‘opacity’?

How can i edit it so that the h1 will just disappear if opacity is not supported?

How do i check if opacity is supported?

How do i make it just disappear if javascript isn’t on?

I welcome any other comments about the way I’ve chosen to do the fade.

(if you’re wondering why I use the ‘y’ variable like that, for some reason when I was decrementing x by 0.1 it was coming out with weird values, changing to 0.90000011234 or something rather than just 0.9)

Thx.

You can use the filter declaration for those other browsers, but you’ll need to make sure hasLayout is active for them, such as:

filter: alpha(opacity=50);
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
display: inline-block;

Or:

filter: alpha(opacity=50);
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
zoom: 1;

For all of those, you would use scripting to add the h1 to the page.

There are ways to detect certain things, but it’s better to proceed instead in a way that won’t break browsers when it’s not supported. That way you will be protected from situations that have not yet been csidered.

That occurs because JavaScript just has double-precision numbers, which tends to affect the decimal accuracy. Just try adding 0.1 + 0.2

Now that you have the filter value (from 0 to 100) you can step back from 100 down to 0 in steps of 10, using that value for the filter and the same value divided by 100 for the opacity percentage.

This might help you get started.

 
    <body>
        <h1  id="myH1" onclick="fadeout(this);">Click Me</h1>
        <script type="text/javascript">
            var step = 0.2;
            var incr = 0.1;
            document.getElementById('myH1').curOpac = 10;
            function fadeout(obj) {
                obj.curOpac = ((obj.curOpac -= incr) < 0)? 0 : obj.curOpac;
                if(typeof(obj.style.opacity) == 'string'){
                    obj.style.opacity = obj.curOpac/10;
                } else { //for older versions of IE
                    obj.style.filter = 'alpha(opacity=' + obj.curOpac*10 + ')';
                }
                if(obj.curOpac > 0){ //haven't finished fading out yet
                    setTimeout(function(){fadeout(obj);},step);
                }
            }
        </script>
    </body>

Thanks so much!

Wow, that is gorgeous. Thanks.
curOpac is a made-up property of the element, right? Much better than my ‘x’. Do I not have to declare new properties, can I just use them like that?

Yes it can. The following might be easier to understand though

obj.curOpac = ((obj.curOpac -= incr) < 0)? 0 : obj.curOpac;

if it were like this instead:


obj.curOpac -= incr;
if (obj.curOpac < 0) {
    obj.curOpac = 0;
}

yes, it’s a user defined property. Javascript objects will have their core properties but javascript lets you assign your own properties to an object. An alternative to what I did could be to use a global variable for the current opacity. I decided to assign the current opacity to the actual object so that you don’t have to use a global variable. If you have multiple elements that fade out then you would need a global variable for each element if you went the global variable route.

By attaching the opacity value to the element you can loop through the elements and assign each of them a property of curOpac (choose any name) and the same onclick function. The onclick function accepts an object reference for the clicked element (via the this keyword) and then sets the opacity of the clicked element independently of any other clicked elements. So you could click a second element while one is still fading out and the fading out of the 2 elements would not interfere with each other. They would fade out independently.

I guess it depends on what you’re used to. I use Excel quite a bit including writing formulas for cells that include conditional statements. If you’re familiar with Excel’s conditional statements you will be aware that they have the same format as the ternary I used (I’m not sure if Excel calls them ternaries as well) in that you have a test condition and if the test returns true, the first value after the test is assigned or if it returns false, the second value after the test is assigned. I like Excel’s format and that is why I usually use a ternary in both javascript and php code.

The ternaries weren’t the focus of such a change, there are good and useful situations for using ternaries.

The problem I was addressing is where the conditional statement also includes code that changes the values within it. In such situations, there can be a greater clarity when there is a separation between the code that assigns new values, and the conditional testing itself.

Thanks.

Hi again,

Was just testing this out on two older pc’s. On their IE8 the fade is MUCH slower than it is on their chrome. I even get the same thing using the exact code you posted above rather than my code. Any ideas why this is? Or ways around it? If I make the fade any faster then on chrome + FF it will just look like an instant pop-up.

I think browsers will display some slightly strange behaviour there because of this variable declaration:

var step = 0.2;

That ‘step’ variable is for the timeout delay in milliseconds. So that code is asking the browser to do the recursive call after 0.2 millisec each time. Given browser overheads, a practical lower limit is roughly, somewhere around 10 millisec. So try setting step to something like 10 or more, instead of the (impossible) 0.2, and it should behave a bit better.

Afraid not Inhicks. That code works fine for me on chrome on those older pc’s, just not on IE8. I also tried it with my own code, using 10/20 milliseconds. Same thing: Chrome + FF - smooth fading. I.E8 - stuttery and reeaallyy slow fading.

I’m sorry if this isn’t a helpful suggestion, but have you tried out jQuery? In terms of browser compatible animations, jQuery is a wonderful library, and as far as I can see it can greatly facilitate the above code/problem.

Thanks for the suggestion. I haven’t even thought of jquery since 4 months ago reading sitepoint’s book ‘build your own website’ and thinking “great but before I use this I should learn some javascript”. Never got back around to learning about jQuery. I’m a bit busy but it’s a good idea to look into using jQuery again. Can’t believe how much I’ve learned in four months.