JavaScript and the DOM have scope. In JavaScript scope is limited, in that there is no block level scope, but the DOM adds some additional levels of scope which may lead to surprising results.
If you click the first populate() button things will work as expected. If, however, you click the second populate button (the first one within the form: bordered by the red dashed border) The function populate exists, but it exists in the global (window) scope. The first button's scope is as such:
window » document » populate (button)
And the one within the form:
window » document » theForm (form) » populate (button)
In the case of the first button, none of the ancestors except window have a member called populate. On the other hand, when searching for the populate function for the second button, the JavaScript engine encounters the form which has an input with id populate, and thus returns a "object does not support this property or method" error.
There are two ways around this. The first is to simply rename the function (or input). The second is to identify the scope of the function.
Please note: it is wrong to have multiple elements with the same id. It serves for demonstration here, but ids should be unique.
function populate() {
new Insertion.Top("log", "Click timestamp: " + new Date().getTime() + "<br />");
}
function doPopulate() {
new Insertion.Top("log", "Click timestamp: " + new Date().getTime() + "<br />");
}
<input id="populate" value="populate()" type="button" onclick="populate();" /> <form action="#" id="theForm"> <input id="populate" value="populate()" type="button" onclick="populate();" /> <input id="populate" value="doPopulate()" type="button" onclick="doPopulate();" /> <input id="populate" value="window.populate()" type="button" onclick="window.populate();" /> </form>