views:

259

answers:

5

I'm trying to write a simple a JS function which randomly rotates the background-image of a CSS block per 1 second. I want to add the name of the block and the number of images from paramaters, so the function can be as flexible as possible and a I can call multiple instances of it on one page. The problem is that I get 'nameofparamter undefined' Error.

Here's the script with the HTML

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="hu-HU" lang="hu">
<head>
<meta name="http-equiv" content="text/html; charset="utf-8"">
<meta name="description" content="leiras"><meta name="keywords" content="kulcsszavak"/>
<style type="text/css"> 
div#mycontainer{
background-image: url(images/bg_image1.jpg);
width: 800px;
height: 600px; 
}
</style>
<script type="text/javascript" charset="utf-8">
function changeBgImage(num, el){
    var imageNum = num;
    var randomImageNum = Math.ceil(Math.random()*imageNum);

    if(el!=='null'){
        el.style.backgroundImage='url(images/bg_image'+randomImageNum+'.jpg';
            var timer = setTimeout("changeBgImage(num, el)", 1000);
    }
}

</script>  
</head>
<title>Dynamic Backgroundimage changer</title>
<body onload="changeBgImage(4, document.getElementById('mycontainer'));">
<div id="mycontainer">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut felis purus, dictum quis pellentesque ut, venenatis et tellus. Phasellus gravida cursus urna, quis hendrerit risus rutrum vel. Suspendisse dictum lobortis molestie. Sed quis lacus nec ante dignissim sollicitudin. Curabitur tristique facilisis turpis.
</div>  
</body>
</html>

I don't really understand 'cause there's the iterated value of both parameters in the body's onload event handler where I call the function? So why undefined? Your help is very much welcomed! :)

+1  A: 

change

setTimeout("changeBgImage(num, el)", 1000);

to

setTimeout(function() { changeBgImage(num, el) }, 1000);
Daniel A. White
+1  A: 

This is a guess but firstly because your invoking the function in quotes it invokes it in the global context, and num and el are not defined in global context, but within your function. Try using a function literal eg

setTimeout( function() { changeBgImage( num, el ) }, 1000 );

PS, you should be using != null not the string null.

meder
+5  A: 

There's a bunch of things that ain't right about your code. For one thing, your null check only checks that the variable does not have a string value that is exactly 'null'. Where you're setting backgroundImage property, the string you're assigning has unmatching parentheses.

But most of all, setTimeout executes on the window context, where your variables are not available (nor should you want them to be). Instead, change your call to

setTimeout(function() { changeBgImage(num, el) }, 1000);

So a complete fix would be

if(el){
    el.style.backgroundImage='url(images/bg_image'+randomImageNum+'.jpg);';
    var timer = setTimeout(function() { changeBgImage(num, el) }, 1000);
}
David Hedlund
This causes every second a new closure being generated, which leads to a memory leak in IE
alemjerus
@alemjerus can you post a screeny of your memory usage graphs?
Breton
A: 

You get it undefined because you transfer to the function "el" in quoted form, as a variable name, which does not exist in called context. To fix this, you need to do it like this:

<script type="text/javascript" charset="utf-8">
function changeBgImage(num, el){
    var imageNum = num;
    var randomImageNum = Math.ceil(Math.random()*imageNum);
document.getElementById(el).style.backgroundImage='url(images/bg_image'+randomImageNum+'.jpg';
            var timer = setTimeout("changeBgImage(num, '" + el + "')", 1000);
}

</script>  
</head>
<title>Dynamic Backgroundimage changer</title>
<body onload="changeBgImage(4, 'mycontainer')
alemjerus
A: 

When you call a function with setTimeout you cannot pass objects as parameters. So I recommend you to approach the problem in other way. You can have shared variables to pass the arguments.

Xim