Determining Element Page Coordinates (4)
To determine an element's true page position, we need functions that will move up through the offset parent hierarchy, adding the offsetLeft and offsetTop values of each parent to those of the element.
Function as Object Method
The offsetParent of the topmost element (BODY) is null, so we can test for the null value to determine when the calculations are finished.
Therefore, we create the getRealLeft() function for finding the x-coordinate:
function getRealLeft() {
xPos = this.offsetLeft;
tempEl = this.offsetParent;
while (tempEl != null) {
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
The function must be defined as a method of an element object:
elementReference.getRealLeft = getRealLeft;
The function, when called, returns a value that we can store in a variable for script use:
trueX = elementReference.getRealLeft()
The function itself declares the xPos variable in which it stores the element's offsetLeft value. In the function, the element is represented by the this keyword, since the function has been defined as a method of the element.
A second variable, tempEl, is declared to represent the element's offsetParent. If tempEl is not null, that is, if we have not finished moving up through the hierarchy, xPos is incremented by the offsetLeft of tempEl, and tempEl is redefined to be its own offsetParent.
When we have finished looping through the parents, xPos will store the element's true left (x) coordinate. This value is returned by the function.
The getRealTop() function works exactly the same way, only with the offsetTop value:
function getRealTop() {
yPos = this.offsetTop;
tempEl = this.offsetParent;
while (tempEl != null) {
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
elementReference.getRealTop = getRealTop;
trueY = elementReference.getRealTop()
Function with Object Argument
If your script prefers to pass the element as an argument, rather than creating an element method, the functions can be mofidified to read:
function getRealLeft(el) {
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null) {
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
function getRealTop(el) {
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null) {
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
Assign the returned values to variables in this way:
trueX = getRealLeft(elementReference);
trueY = getRealTop(elementReference);
Function as Object Method or Object Argument
If you can't decide how you prefer the functions (method or argument), they can be made flexible. In the following version, an argument is specified. If the argument is not passed, that is, if the arguments.length is 0, then the script is using the function as a method. The this keyword is then assigned to the variable that represents the argument (el).
function getRealLeft(el) {
if (arguments.length==0) el = this;
xPos = el.offsetLeft;
tempEl = el.offsetParent;
while (tempEl != null) {
xPos += tempEl.offsetLeft;
tempEl = tempEl.offsetParent;
}
return xPos;
}
function getRealTop(el) {
if (arguments.length==0) el = this;
yPos = el.offsetTop;
tempEl = el.offsetParent;
while (tempEl != null) {
yPos += tempEl.offsetTop;
tempEl = tempEl.offsetParent;
}
return yPos;
}
This version of the functions can be called in either of these two ways:
elementReference.getRealLeft = getRealLeft;
elementReference.getRealTop = getRealTop;
trueX = elementReference.getRealLeft()
trueY = elementReference.getRealTop()
or:
anotherTrueX = getRealLeft(elementReference);
anotherTrueY = getRealTop(elementReference);
Now, you will never again lose your elements! |