initiation not working

W

windandwaves

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
 
W

web.dev

windandwaves said:
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


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); };
}
 
W

windandwaves

web.dev said:
windandwaves said:
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


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!
 
M

Michael Winter

web.dev said:
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]
[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
 
W

windandwaves

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top