2

Could someone please help me with this. First let me put up the code.

HTML:

<div id="FirstChild" style=" background-color: red; width: 100px; height: 50px; margin: 5px;"></div>

JavaScript:

 window.onload = someThing;

 function someThing(){
    window.onclick = WidthChange;
 }


function WidthChange(){ 
    var presentWidth = parseInt(document.getElementById("FirstChild").style.width);
    document.getElementById("FirstChild").style.width = presentWidth + 1 +"px";
    setTimeout(WidthChange(), 3000);
}

Now, I want to increase the width of the div by 1 px after every 3 second when the user clicks on the window. I want this to happen forever. But it doesnt work. When I click on the window, the width immediately increases. I know how to do it with jQuery animate() and I don't want to use that. Only Javascript please!

David
  • 8,340
  • 7
  • 49
  • 71
Navneet Saini
  • 934
  • 4
  • 16
  • 33
  • 1
    possible duplicate of [slide a div using javascript](http://stackoverflow.com/questions/8050905/slide-a-div-using-javascript) – David Mar 19 '13 at 09:08

2 Answers2

2

The with immediately increases because you're not setting a timed out call to the function, but setting a timedout call to the return value of that widthchange function. Replace setTimeout(WidthChange(), 3000); with setTimeout(WidthChange, 3000).
While you're at it, please also consider doing something about this:

presentWidth + 1 +"px";

You're doing two things at once here: adding ints together and concatenating strings. Just be clear as to which you want to do first:

(presentWidth +1) +"px";

Or just seperate this into two statements.

Lastly: convention dictates that functions that start with a capital letter are constructors, not just functions/event handlers. so perhaps change WidthChange to widthChange, too?

Update
The difference between setTimeout(WidthChange, 3000) and setTimeout(WidthChange(), 3000) is quite simple. JS regards WidthChange() as an expression, that needs to be resolved to a value (like a fracture in maths). The expression calls a function, so it can be resolved to the return value of that function call. Hence, the function is called immediatly, not after 3000ms.
In the version without the parentheses, the value passed to setTimeout as first argument is a reference to a function, which is impossible to resolve further/simplify. That function is what setTimeout will call after the timeout has expired. Just google setTimeout MDN (and bookmark MDN) if this isn't clear to you.

Elias Van Ootegem
  • 74,482
  • 9
  • 111
  • 149
  • FYI, there is no need for parentheses, because such expressions are always evaluated left-to-right. (Operator precedence does not come into play here, since it’s the same operator twice.) – CBroe Mar 19 '13 at 09:19
  • Could you please explain me again the difference between setTimeout(WidthChange, 3000) and etTimeout(WidthChange(), 3000); or give me some link where I clear my doubt about this concept! – Navneet Saini Mar 19 '13 at 09:21
  • @Navneet, the first one passes the reference to the function as parameter to setTimeout, while the second one executes the function there and then, and passes only the _return value_ of that function to setTimout (which _usually_ is not what you want – a function returning a function reference is possible, but not a typical use case.) – CBroe Mar 19 '13 at 09:23
  • Thanks a lot! Will this code work for all browsers or should I add something to make it more compatible? – Navneet Saini Mar 19 '13 at 09:26
  • @NavneetSaini: I edited my answer to explain the difference. on the X-browser front, I can tell you that using `window.onload` like that does create [a mem-leak in IE<9](http://stackoverflow.com/questions/11186750/memory-leak-risk-in-javascript-closures) but as it now stands, I'd say work at it some more, until everything is in working order. Then start tweaking and refining those little things – Elias Van Ootegem Mar 19 '13 at 09:26
  • @NavneetSaini: Glad I could help... do look into some of the trickery I use in the snippets I posted in the question on mem-leaks and closures. Especially the answer that shows how to avoid those leaks. – Elias Van Ootegem Mar 19 '13 at 09:32
0

In your code-

  var presentWidth = parseInt(document.getElementById("FirstChild").style.width);

Now time to setTimeout -

setTimeout(function() { document.getElementById('FirstChild').style.width = (presentWidth+1)+"px" },
               3000);
Manoz
  • 6,507
  • 13
  • 68
  • 114