I am trying to figure out how to dynamically create onclick attributes at page load. Let's say I want to call a function every time I click any div tag with class="thumb". If I call the function "test" without passing a value via parentheses, it works. If I want to pass a value, it will not work. Below I create a global variable div_list, and call init through the body's onload:
function test () { alert('clicked') }
var div_list = ""
function init () {
div_list = document.getElementsByTagName('div');
for (var i = 0; i < div_list.length; i++) {
if (div_list[i].className == "thumb") {
div_list[i].onclick = test;
}
}
}
This actually works. What does not work, is if I replace the onclick with
div_list[i].onclick = test();
I need to be able to do that, because my eventual goal is something more like this:
div_list[i].onclick = overlayOn(480,div_list[i].childNodes[0].childNodes[0]);
Any ideas on how to tackle test() first?
TIA
Bill Posters
12-13-2005, 07:12 PM
e.g.
div_list[i].onclick = function() { test(); }
…
div_list[i].onclick = function() { overlayOn(480,div_list[i].childNodes[0].childNodes[0]); }
div_list[i].onclick = function() { overlayOn(480,div_list[i].childNodes[0].childNodes[0]); }
This kind of stuff woun't work, as the loop is external, so that the moment the event is activated, the loop is already finished, so that all the time [i] will be the last indent of the loop. Usually you should must have repeated the loop inside, but in your case it will be enough to self reference the element:
div_list[i].onclick = function() { overlayOn(480,this.childNodes[0].childNodes[0]); }
On the other hand, take care when dealing with childNodes reference, as IE and Mozilla count in different ways childNodes. Moz counts all the possible textNodes, even if empty (the gaps), while IE counts only some of them.
Bill Posters
12-14-2005, 10:56 AM
…
Good catch. I wasn't really paying attention to what was in the function itself.
MtBiker
12-14-2005, 11:09 PM
Here is the exact code that ended up working beautifully in Firefox:
div_list[i].onclick = eval("function() { overlayOn(" + layer + ",div_list[" + i + "].childNodes[0].childNodes[0]); }");
...where typically layer=480
However, it does not work in IE6. I installed MS script debugger, but had hoped to have a chance to look at it again today so that I could post a more comprehensive answer. I should prob do an alert after page load to see what the onclick is set to for each div. Instantiating div_list inside or outside of the create_onclicks function seems to make no difference to IE, so it's almost magic that the onclick value is created properly in Firefox as "this" instead of pointing to an array element that's doesn't exist(?)
If you want to see how far along I've come, you can check it out:
http://jamiedamanpour.com/photos/elizabeth_furnace/
The pertinent function is create_onclicks at the bottom of this:
http://jamiedamanpour.com/photos/gallery.js
This is my first time at this forum. Thanks for the interest and advice.
this would've prevented the use of eval
div_list[i].onclick = function() {
var x = i;
overlayOn(480,div_list[x].childNodes[0].childNodes[0]);
}
rarely(in my experience) is there a need for eval unless maybe you're doing something using the JSON approach.
change this (and any other use of eval)
eval( "window.document.image_" + layer + ".src = '" + imagePath + "'" );
to this
window.document.["image_" + layer ].src = imagePath;
refer to the link in glenngv (http://www.codingforums.com/member.php?u=42)'s for more details, Square Bracket Notation:
http://jibbering.com/faq/faq_notes/square_brackets.html
liorean
12-15-2005, 12:36 AM
fci: He's actually using eval as a kind of constructor here, instead of new Function(...). He needs the binding to happen at assignment, not at triggering as that would do.
var
div_list;
function makeHandler(i,j){
return function(evt){
overlayOn(j,div_list.item(i).firstChild.firstChild);};
}
function init(){
var
i,
o;
div_list=document.getElementsByTagName('div');
for(;o=div_list.item(i);i++)
if(/\bthumb\b/.test(o))
o.onclick=makeHandler(i,480);
}
Actually, this is a pretty neat way to code an event handler without having iew leak memory like a sieve.