I'm learning javascript. My first idea has led to a problem. I'm trying to set up strings to load at random intervals on different parts of the page, but I don't know the right function to use with setTimeout(). I hear "don't use document.write" and "probably don't use innerHTML", but are other functions outside of javascript? Please help.

For instance, why won't this code work?

// this is in the head, other functions working fine
function addTextNode() {
    var newtext = document.createTextNode(" Some text added dynamically. ");
    var para = document.getElementById("p1");
    window.setTimeout("para.appendChild(newtext);", 1000);
}
//this is in the body
<div style="border: 1px solid red">
    <p id="p1">First line of paragraph.</p>
</div><br />

<button onclick="addTextNode();">add another textNode</button>

setTimeout() can also take a function as the first parameter.

Using an anonymous function you can rewrite your JS code as:

// example of using a JS closure to persist a lexical environment/scope
function addTextNode() {
    var newtext = document.createTextNode(" Some text added dynamically. ");
    var para = document.getElementById("p1");
    window.setTimeout(function() { para.appendChild(newtext); }, 1000);
}

What happens is that setTimeout() is executed in the scope of the window (global scope). The variables "newtext" and "para" are private to the function addTextNode(), thus they only exist in the scope of that function.

When you however use a function instead of a string as the first parameter of setTimeout(), what happens is that JS will create a closure that makes "para" and "newtext" available in the scope of the anonymous function.

This is a valuable part of the JS language that will take care of scope issues for you instead of having you resort to using the global scope.

You could also use the global scope:

eg:

// example of using a JS closure to persist a lexical environment/scope
function addTextNode() {
    newtext = document.createTextNode(" Some text added dynamically. ");
    para = document.getElementById("p1");
    window.setTimeout("para.appendChild(newtext);", 1000);
}

but you will run into issues of overwriting the variables as they are available globally.

The closure is private to the function creating the closure however. So it cannot be overwritten from the global scope.

This is used a lot with the XMLHttpRequest object. And also with Event handlers, mostly unknowingly.

This article has been dead for over six months. Start a new discussion instead.