initiation not working

Discussion in 'Javascript' started by windandwaves, Mar 15, 2006.

  1. windandwaves

    windandwaves Guest

    Hi Folk

    Have a look at

    http://www.corstorphine.co.nz/_quiz/quiz.php


    Onload I do this:

    function load_images() {
    if (!check()) return;
    var nav = document.getElementById('frm');
    var imgs = nav.getElementsByTagName('img');
    var x = 0;
    for (var i =0;i<imgs.length;i++) {
    imgs.number = i;
    imgs.onclick = select_image;
    var y = 'c' + x;
    clicker = new getObj(y);
    clicker.obj.onclick = function () {tick_image(x);};
    x++;
    }

    (see http://www.corstorphine.co.nz/_quiz/j.js)

    However, if I make tick_image like this:

    tick_image(x) {
    alert(x);
    }
    then I always get 12 rather than a number between 0 and 11.

    Just have a look at it, please, I cant really explain it all here, but
    basically I dont understand why in the following line:

    clicker.obj.onclick = function () {tick_image(x);};

    x always becomes 12 while it clearly should be between 0 and 12.

    TIA

    > Nicolaas
    windandwaves, Mar 15, 2006
    #1
    1. Advertising

  2. windandwaves

    web.dev Guest

    windandwaves wrote:
    > Hi Folk
    >
    > Have a look at
    >
    > http://www.corstorphine.co.nz/_quiz/quiz.php
    >
    >
    > Onload I do this:
    >
    > function load_images() {
    > if (!check()) return;
    > var nav = document.getElementById('frm');
    > var imgs = nav.getElementsByTagName('img');
    > var x = 0;
    > for (var i =0;i<imgs.length;i++) {
    > imgs.number = i;
    > imgs.onclick = select_image;
    > var y = 'c' + x;
    > clicker = new getObj(y);
    > clicker.obj.onclick = function () {tick_image(x);};
    > x++;
    > }
    >
    > (see http://www.corstorphine.co.nz/_quiz/j.js)
    >
    > However, if I make tick_image like this:
    >
    > tick_image(x) {
    > alert(x);
    > }
    > then I always get 12 rather than a number between 0 and 11.
    >
    > Just have a look at it, please, I cant really explain it all here, but
    > basically I dont understand why in the following line:
    >
    > clicker.obj.onclick = function () {tick_image(x);};
    >
    > x always becomes 12 while it clearly should be between 0 and 12.
    >
    > TIA
    >
    > > Nicolaas


    You need to separate the assignment of functions when you want to pass
    a variable to a function. For example:

    for( etc. )
    {
    attachFunction( click, x );
    }

    ....

    function attachFunction(oClick, x)
    {
    oClick.onclick = function() { tick_image(x); };
    }
    web.dev, Mar 15, 2006
    #2
    1. Advertising

  3. windandwaves

    windandwaves Guest

    web.dev wrote:
    > windandwaves wrote:
    >> Hi Folk
    >>
    >> Have a look at
    >>
    >> http://www.corstorphine.co.nz/_quiz/quiz.php
    >>
    >>
    >> Onload I do this:
    >>
    >> function load_images() {
    >> if (!check()) return;
    >> var nav = document.getElementById('frm');
    >> var imgs = nav.getElementsByTagName('img');
    >> var x = 0;
    >> for (var i =0;i<imgs.length;i++) {
    >> imgs.number = i;
    >> imgs.onclick = select_image;
    >> var y = 'c' + x;
    >> clicker = new getObj(y);
    >> clicker.obj.onclick = function () {tick_image(x);};
    >> x++;
    >> }
    >>
    >> (see http://www.corstorphine.co.nz/_quiz/j.js)
    >>
    >> However, if I make tick_image like this:
    >>
    >> tick_image(x) {
    >> alert(x);
    >> }
    >> then I always get 12 rather than a number between 0 and 11.
    >>
    >> Just have a look at it, please, I cant really explain it all here,
    >> but basically I dont understand why in the following line:
    >>
    >> clicker.obj.onclick = function () {tick_image(x);};
    >>
    >> x always becomes 12 while it clearly should be between 0 and 12.
    >>
    >> TIA
    >>
    >>> Nicolaas

    >
    > You need to separate the assignment of functions when you want to pass
    > a variable to a function. For example:
    >
    > for( etc. )
    > {
    > attachFunction( click, x );
    > }
    >
    > ...
    >
    > function attachFunction(oClick, x)
    > {
    > oClick.onclick = function() { tick_image(x); };
    > }


    I have no idea why but it works! Would you care explaining it? It looks
    great now!
    windandwaves, Mar 15, 2006
    #3
  4. On 15/03/2006 21:05, windandwaves wrote:

    > web.dev wrote:
    >
    >> windandwaves wrote:


    [snip]

    >>> function load_images() {
    >>> if (!check()) return;
    >>> var nav = document.getElementById('frm');
    >>> var imgs = nav.getElementsByTagName('img');
    >>> var x = 0;
    >>> for (var i =0;i<imgs.length;i++) {
    >>> imgs.number = i;
    >>> imgs.onclick = select_image;
    >>> var y = 'c' + x;
    >>> clicker = new getObj(y);
    >>> clicker.obj.onclick = function () {tick_image(x);};
    >>> x++;
    >>> }


    [snip]

    >>> then I always get 12 rather than a number between 0 and 11.


    [snip]

    >> You need to separate the assignment of functions when you want to
    >> pass a variable to a function.


    [snip]

    > I have no idea why but it works! Would you care explaining it?


    This is a rather fundamental feature of inner functions, and therefore
    closures.

    An inner function maintains a reference to the Variable object of each
    outer function in a stack, ending with the global object. This is the
    scope chain. The Variable objects it references contain local variables
    as properties. It is the scope chain that is used to resolve identifiers.

    Each time your loop executes, a new function object is created, and a
    reference is assigned to the onclick property. While each object is new,
    the scope chain is exactly the same. This means that each function
    object shares the same set of variables as each one reference the same
    Variable objects.

    The conclusion? If one function changes the value of a variable, all of
    these inner functions sees that change. Now, whilst your function
    doesn't perform any modifications, the loop code does and the effect is
    the same: by the end of the loop, each function will read the variable,
    i, to be the value of img.length.

    [snip]

    By the way, you should consider removing those event listeners (assign
    null to the onclick properties) when the document unloads to avoid
    invoking IE's notorious memory leak.

    You should also remove

    clicker.obj.onclick = function () {tick_image(x);};

    from the load_images function. It's redundant now.

    Mike

    --
    Michael Winter
    Prefix subject with [News] before replying by e-mail.
    Michael Winter, Mar 15, 2006
    #4
  5. windandwaves

    windandwaves Guest

    Michael Winter wrote:

    [big snip and a big thank you for the exaplanation - I am slowly working out
    that javascript treats variables very different from the other languages
    that I know (VB + PHP)]

    > By the way, you should consider removing those event listeners (assign
    > null to the onclick properties) when the document unloads to avoid
    > invoking IE's notorious memory leak.


    DONE!

    > You should also remove
    >
    > clicker.obj.onclick = function () {tick_image(x);};
    >
    > from the load_images function. It's redundant now.


    YEP - thank you.


    > Nicolaas
    windandwaves, Mar 15, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Ratman
    Replies:
    0
    Views:
    644
    Ratman
    Sep 14, 2004
  2. Nathaniel Sherman
    Replies:
    5
    Views:
    3,338
  3. irfan
    Replies:
    2
    Views:
    508
    tom fredriksen
    Feb 20, 2006
  4. irfan
    Replies:
    1
    Views:
    341
    tom fredriksen
    Mar 21, 2006
  5. damiaotomas

    Matrix initiation

    damiaotomas, Nov 5, 2003, in forum: C++
    Replies:
    0
    Views:
    426
    damiaotomas
    Nov 5, 2003
Loading...

Share This Page