Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    New to the CF scene
    Join Date
    Dec 2005
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    dynamically creating onclick attributes at page load

    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

  • #2
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    e.g.
    Code:
    div_list[i].onclick = function() { test(); }
    …
    div_list[i].onclick = function() { overlayOn(480,div_list[i].childNodes[0].childNodes[0]); }

  • #3
    Kor
    Kor is offline
    Red Devil Mod Kor's Avatar
    Join Date
    Apr 2003
    Location
    Bucharest, ROMANIA
    Posts
    8,478
    Thanks
    58
    Thanked 379 Times in 375 Posts
    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.
    Last edited by Kor; 12-14-2005 at 08:35 AM.
    KOR
    Offshore programming
    -*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*

  • #4
    Senior Coder
    Join Date
    Feb 2003
    Posts
    1,665
    Thanks
    0
    Thanked 27 Times in 25 Posts
    Quote Originally Posted by Kor
    Good catch. I wasn't really paying attention to what was in the function itself.

  • #5
    New to the CF scene
    Join Date
    Dec 2005
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts
    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.

  • #6
    fci
    fci is offline
    Senior Coder
    Join Date
    Aug 2004
    Location
    Twin Cities
    Posts
    1,345
    Thanks
    0
    Thanked 0 Times in 0 Posts
    this would've prevented the use of eval
    Code:
    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)
    Code:
    eval( "window.document.image_" + layer + ".src = '" + imagePath + "'" );
    to this
    Code:
    window.document.["image_" + layer ].src = imagePath;
    refer to the link in glenngv's for more details, Square Bracket Notation:
    http://jibbering.com/faq/faq_notes/square_brackets.html

  • #7
    Master Coder
    Join Date
    Feb 2003
    Location
    Umeå, Sweden
    Posts
    5,575
    Thanks
    0
    Thanked 83 Times in 74 Posts
    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.
    Code:
    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.
    liorean <[lio@wg]>
    Articles: RegEx evolt wsabstract , Named Arguments
    Useful Threads: JavaScript Docs & Refs, FAQ - HTML & CSS Docs, FAQ - XML Doc & Refs
    Moz: JavaScript DOM Interfaces MSDN: JScript DHTML KDE: KJS KHTML Opera: Standards


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •