PDA

View Full Version : variable scope problem with prototype and event



Bonker
Jul 18th, 2005, 03:25 PM
Hi everyone

I wrote a method to add to all arrays, which swaps two values at a specified index. But when I try to use it with an event handler it no longer works. In the example http://www.speich.net/tests/test01.htm the hardcoded links work, but not the click on the buttons, which are setup onload.

This seems to be a scope problem, but I don't really understand it and I don't know how to solve it. Any help would be appreceated.

Thanx a lot Bonker




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

<script type="text/javascript">

var arrFldName = new Array('author','year','title','publ');

function SwapIndex(Id) {
// add new method to array object, which moves swapes values at specified index
var Arr1 = this.slice(0, Id + 1);
var Arr2 = this.slice(Id + 1);
if (Id == this.length - 1) {
var Val = this.pop(); // remove last el
this.unshift(Val); // insert first
return this;
}
else {
var Val1 = Arr1.pop(); // remove last of first array
var Val2 = Arr2.shift(); // remove first of second
Arr1.push(Val2); // append at end
Arr2.unshift(Val1); // insert first
Arr1 = Arr1.concat(Arr2);
var i = 0;
var Len = Arr1.length;
for (;i < Len; i++) { this[i] = Arr1[i]; }
return this;
}
}
Array.prototype.SwapIndex = SwapIndex;

function Move() {
if (arguments.length > 0) var Id = arguments[0];
else Id = this.id.slice(this.id.lastIndexOf('_') + 1);

arrFldName.SwapIndex(Id);
for (var i = 0; i < arrFldName.length; i++) {
var Ref = document.getElementById('Txt_' + i);
document.getElementById('Txt_' + i).firstChild.data = arrFldName[i];
}
}

function Init() {
// setup buttons
for (var i = 0; i < 3; i++) {
// move right
var Ref = document.getElementById('ImgMoveRight_' + i);
Ref.onclick = Move;
Ref = document.getElementById('ImgMoveLeft_' + i);
Ref.onclick = Move;
}
}

window.onload = Init;

</script>
</head>

<body>
<table border="0">
<tr>
<td><a href="#" onclick="Move(0)">--></a></td>
<td>&nbsp;</td>
<td><a href="#" onclick="Move(1)">--></a></td>
<td>&nbsp;</td>
<td><a href="#" onclick="Move(2)">--></a></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td><img src="images/MoveRight.gif" id="ImgMoveRight_0" /></td>
<td>&nbsp;</td>
<td><img src="images/MoveLeft.gif" id="ImgMoveLeft_0" /><img src="images/MoveRight.gif" id="ImgMoveRight_1" /></td>
<td>&nbsp;</td>
<td><img src="images/MoveLeft.gif" id="ImgMoveLeft_1" /><img src="images/MoveRight.gif" id="ImgMoveRight_2" /></td>
<td>&nbsp;</td>
<td><img src="images/MoveLeft.gif" id="ImgMoveLeft_2" /></td>
</tr>
<tr>
<td id="Txt_0">author</td>
<td>---</td>
<td id="Txt_1">year</td>
<td>---</td>
<td id="Txt_2">title</td>
<td>---</td>
<td id="Txt_3">publication</td>
</tr>
</table>
</body>
</html>

Mr J
Jul 18th, 2005, 06:28 PM
See if the following will work for that function



function Init() {
// setup buttons
for (var i = 0; i < 3; i++) {
// move right
var Ref = document.getElementById('ImgMoveRight_' + i);
Ref.onclick = function(){Move(i)}
Ref = document.getElementById('ImgMoveLeft_' + i);
rev=2-i
Ref.onclick = function(){Move(rev)}

}
}

Bonker
Jul 19th, 2005, 08:03 AM
I had already tried what you suggest. If you put an alert in the move function to show what the value of Id is, it's always 3, only the last used i gets strored in the anonymous function, all previous are overwritten.

Bonker
Feb 16th, 2006, 12:46 PM
Several months later and with quite a bit more experience I found the solution (no it didn't take me that long, I just checked my old posts and realized that by now I would know the solution. So here it is:



var Ref = document.getElementById('ImgMoveRight_' + i);
Ref.onclick = function() {
var Key = i;
Move(Key);
}


but this doesn't (at least not as intended):


var Ref = document.getElementById('ImgMoveRight_' + i);
Ref.onclick = function() {
Move(i);
}

because the variable i is always 3 when the event click is called, but you can create a new variable and store each i, when the loop is called. Then when you click it is either 0,1 or 2 as intended.

Bonker
Feb 16th, 2006, 12:55 PM
Hi again

If you want to see a working example of what I was talking about, you can check out this page (http://www.lfi.ch/publikationen/publ_auszug.php). Unfortunately it is in German. But if you click the left/right buttons you'll get the idea.