...

View Full Version : Problem with Null Elements



KevinJohnson
05-12-2009, 11:58 AM
For some strange reason, i seem to be having a problem with passing element values to a Function paramater in my code.
I'm developing this on FireFox3 and only FireFox (not IE, Opera or any others). So no need to worry about cross-browser compatibility or anything like that.
I had this same problem before, but i forgot how i fixed it.

The function that i seem to be having a problem with is called:
SnapToGrid(e);

It's function is to align a picture element to the nearest square (on the chess board) after the mouse button is released (after the picture element has been dragged)

Here is the entire project (DHTML App) with image files
http://daomingjin.googlepages.com/ChessApp-Broken.zip

The error that i keep getting is that "element is null" when infact, i know that the element is not null, because there is an onclick="" event that is able to function without any problems.

here's the SnapToGrid(e) function:


function SnapToGrid(e)
{
// init the Chess Board Position Data Array space
var Coords = new Array(9);
for (i=1; i <9; i++)
{
Coords[i]= new Array(9);
}

//set the Chess Board Position Data Array
//manually set the positions for the Coord[x][y] array
//row 1
Coords[1][1] = " 0px 0px"
Coords[2][1] = " 50px 0px"
Coords[3][1] = "100px 0px"
Coords[4][1] = "150px 0px"
Coords[5][1] = "200px 0px"
Coords[6][1] = "250px 0px"
Coords[7][1] = "300px 0px"
Coords[8][1] = "350px 0px"

//row 2
Coords[1][2] = " 0px 50px"
Coords[2][2] = " 50px 50px"
Coords[3][2] = "100px 50px"
Coords[4][2] = "150px 50px"
Coords[5][2] = "200px 50px"
Coords[6][2] = "250px 50px"
Coords[7][2] = "300px 50px"
Coords[8][2] = "350px 50px"

//row 3
Coords[1][3] = " 0px 100px"
Coords[2][3] = " 50px 100px"
Coords[3][3] = "100px 100px"
Coords[4][3] = "150px 100px"
Coords[5][3] = "200px 100px"
Coords[6][3] = "250px 100px"
Coords[7][3] = "300px 100px"
Coords[8][3] = "350px 100px"

//row 4
Coords[1][4] = " 0px 150px"
Coords[2][4] = " 50px 150px"
Coords[3][4] = "100px 150px"
Coords[4][4] = "150px 150px"
Coords[5][4] = "200px 150px"
Coords[6][4] = "250px 150px"
Coords[7][4] = "300px 150px"
Coords[8][4] = "350px 150px"

//row 5
Coords[1][5] = " 0px 200px"
Coords[2][5] = " 50px 200px"
Coords[3][5] = "100px 200px"
Coords[4][5] = "150px 200px"
Coords[5][5] = "200px 200px"
Coords[6][5] = "250px 200px"
Coords[7][5] = "300px 200px"
Coords[8][5] = "350px 200px"

//row 6
Coords[1][6] = " 0px 250px"
Coords[2][6] = " 50px 250px"
Coords[3][6] = "100px 250px"
Coords[4][6] = "150px 250px"
Coords[5][6] = "200px 250px"
Coords[6][6] = "250px 250px"
Coords[7][6] = "300px 250px"
Coords[8][6] = "350px 250px"

//row 7
Coords[1][7] = " 0px 300px"
Coords[2][7] = " 50px 300px"
Coords[3][7] = "100px 300px"
Coords[4][7] = "150px 300px"
Coords[5][7] = "200px 300px"
Coords[6][7] = "250px 300px"
Coords[7][7] = "300px 300px"
Coords[8][7] = "350px 300px"

//row 8
Coords[1][8] = " 0px 350px"
Coords[2][8] = " 50px 350px"
Coords[3][8] = "100px 350px"
Coords[4][8] = "150px 350px"
Coords[5][8] = "200px 350px"
Coords[6][8] = "250px 350px"
Coords[7][8] = "300px 350px"
Coords[8][8] = "350px 350px"

// After the piece is moved, center that piece on the closest square

// get the recently moved piece's current location
var xCoord = document.getElementById(e).style.left; // x coordinate
var yCoord = document.getElementById(e).style.top; // y coordinate

var BlockSize = 50;

// Loop through all of the different Coordinates of the Blocks on the chess board

for (x=1; x <9; x++)
{
for (y=1; y <9; y++)
{
//coordinate variables of the current block being tested
var BoardXcoord = document.getElementById(e).style.left = Coords[x][y].substr(0,3);
var BoardYcoord = document.getElementById(e).style.top = Coords[x][y].substr(6,8);

if (xCoord > BoardXcoord && xCoord < xCoord + BlockSize)
{
if (yCoord > BoardYcoord && yCoord < yCoord + BlockSize)
{
// set align the piece to the closest square
document.getElementById(e).style.left = Coords[x][y].substr(0,3);
document.getElementById(e).style.top = Coords[x][y].substr(6,8);

}
}
}
}
}

venegal
05-12-2009, 01:59 PM
Are you sure you are passing the element id into the function, and not the element itself?

Please post the code calling the function, and/or provide a link.

As a side note, it's probably easier to set the grid coordinates in a loop instead of manually:


function setGridCoords(squareLength, numberOfSquaresInRow){
var Coords = [];
for (var x = 1; x <= numberOfSquaresInRow; x++){
Coords[x] = [];
for (var y = 1; y <= numberOfSquaresInRow; y++){
Coords[x][y] = {
'x': x * squareLength,
'y': y * squareLength
};
}
}
return Coords;
}

var Coords = setGridCoords(50, 8);


This format would also eliminate those awkward substr calls; you could use the array like this:


var BoardXcoord = document.getElementById(e).style.left = Coords[x][y].x;
var BoardYcoord = document.getElementById(e).style.top = Coords[x][y].y;

venegal
05-12-2009, 02:18 PM
After having another look I think you might want to make the whole function a little less awkward. Instead of comparing to all the grid coordinates in nested loops, you can simply let it snap by rounding the coordinates to the nearest multiple of the square size.

Your code could look something like this


function SnapToGrid(e){
var elementX = document.getElementById(e).style.left;
var elementY = document.getElementById(e).style.top;

elementX = (Math.floor(parseInt(elementX) / blockSize) * blockSize) + " px";
elementY = (Math.floor(parseInt(elementY) / blockSize) * blockSize) + " px";
}

var blockSize = 50;


and still do the same thing as your whole snippet.

KevinJohnson
05-12-2009, 04:08 PM
Here is the link to all of the code:

http://daomingjin.googlepages.com/ChessApp-Broken.zip

that .ZIP file has the HTML file and all of the image files.

venegal
05-12-2009, 05:01 PM
Thanks. Just as I thought, e in your SnapToGrid function is not the id of the element but the mouse event object.

And, I'm not kidding, do something about your copy/paste code duplication all over the place coding style. It's very bad form.

Kick the whole convoluted SnapToGrid function in favor of this


function SnapToGrid(e){
e.target.style.left = (Math.floor(parseInt(e.target.style.left) / blockSize) * blockSize) + "px";
e.target.style.top = (Math.floor(parseInt(e.target.style.top) / blockSize) * blockSize) + "px";
}
var blockSize = 50;

and it will work.

Edit: And as an exercise, write the SetPieces function in less than 10 lines.

KevinJohnson
05-12-2009, 05:39 PM
i keep getting and error (no matter how i call the function):

e.target not defined


i'm used to refering to DOM objects by using the getDocumentById()

KevinJohnson
05-12-2009, 05:42 PM
Thanks. Just as I thought, e in your SnapToGrid function is not the id of the element but the mouse event object.

And, I'm not kidding, do something about your copy/paste code duplication all over the place coding style. It's very bad form.

Kick the whole convoluted SnapToGrid function in favor of this


function SnapToGrid(e){
e.target.style.left = (Math.floor(parseInt(e.target.style.left) / blockSize) * blockSize) + "px";
e.target.style.top = (Math.floor(parseInt(e.target.style.top) / blockSize) * blockSize) + "px";
}
var blockSize = 50;

and it will work.

Edit: And as an exercise, write the SetPieces function in less than 10 lines.

I think the only way to write the SetPieces function in less than 10 lines would be to make an Indexed Array of elements. Correct?

venegal
05-12-2009, 06:05 PM
There will have to be an array containing the names of the pieces in the right order, yes.

And "10" was only an arbitrary number off the top of my head, but I guess it might be done.

Edit: Sorry, I didn't see the post up there where you said it didn't work. I tested it myself on FF3, just like you, and it works. Could you please post the current version of the code you are working with, so I can see where the problem lies?

And: Using getElementById is fine, if you put an id into it, but event objects hold the DOM element itself, not its id.

venegal
05-12-2009, 06:33 PM
Here's my go at it. Not exactly 10 lines, but you get the idea.


function SetPieces(){
var pieces = ["Castle1", "Knight1", "Rook1", "King", "Queen", "Rook2", "Knight2", "Castle2"];
var setPieces = function(color, row){
var pawnRowOffset = {'White': -1, 'Black': 1};
for (var i = 0; i < pieces.length; i++) {
document.getElementById(color + pieces[i] + "Image").style.left = i * blockSize + "px";
document.getElementById(color + pieces[i] + "Image").style.top = (row - 1) * blockSize + "px";
document.getElementById(color + "Pawn" + (i + 1) + "Image").style.left = i * blockSize + "px";
document.getElementById(color + "Pawn" + (i + 1) + "Image").style.top = (row - 1 + pawnRowOffset[color]) * blockSize + "px";
}
}
setPieces("White", 8);
setPieces("Black", 1);
}

And sorry I took the exercise away from you, but you still got a whole lot more in there to rewrite.

KevinJohnson
05-12-2009, 07:00 PM
don't worry...about the whole exercise thing. I have been away from serious programming for about 3 years. Just getting back into it again (job related). So i find that when i look at other people's code there's always something to learn.

My main goal right now is to get up to speed again on DHTML apps. I want to make some useful SPAs (single page applications) other than TiddlyWiki.

KevinJohnson
05-12-2009, 07:47 PM
nevermind, i fixed it :P

KevinJohnson
05-13-2009, 06:04 AM
thanks for all the help :thumbsup:



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum