473,760 Members | 10,633 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Inaccuracies in absolute positioning

Demo page at http://csaba.org/Demos/getRect.htm

One question I've seen come up multiple times is:
How can I find the abolute position of my favorite element
on the page? The standard answer is not working for me
on any of IE/Netscape/Opera! The above page demonstrates
the problem. I'd love to know how to make it work correctly.

The usual answer, which I have been using, too, is something like:
function getRect(elem) {
// return (Left,Top,Right ,Bottom) of the element
var myRect = Array(elem.offs etLeft, elem.offsetTop,
elem.offsetLeft + elem.offsetWidt h,
elem.offsetTop + elem.offsetHeig ht)
if (!elem.offsetPa rent) return myRect;
newRect = getRect(elem.of fsetParent)
for (var i=0;i<4;i++) myRect[i] = myRect[i] + newRect[i % 2];
return myRect;
}

This is close, but I am not doing government work, and I need something
exact. Specifically, As I move my mouse around a table, whenever the
mouse passes over a table border, I want to be able to identify which
two cells it is between. Let's leave that problem alone for now, since it's
much more difficult (when rowspan/colspan are involved) and just
concentrate on figuring out when the mouse is over an external border.
Now the mouse already knows which element it is over, and you can see
this as the mouse changes form as it goes from one cell, over
a border, then to another.

So the plan is that whenever the table gets an onmouseover event,
we'll compare the mouse position to the top left TD and the bottom
right TD element to find out if we're at an external border.
My IE 5.5, NN 6.1 and Opera 7.01 on Win 2K Pro all fail these
comparisons on exactly two borders each, and we are talking that there
is a two pixel difference! The observed behaviour is that when you
approach the border from the outside, it always works but going from
the inside to the outside of the table it fails on two borders because of
the two pixel difference.

Can anyone spot how to fix this problem up?
Thanks for any tips,
Csaba Gabor from New York

PS. OK, the code to test for the right border cannot assume that the
last cell of the last row is rightmost in the table, but let's not worry
about that till after the main problem is solved.
Jul 20 '05 #1
2 4299
"Csaba2000" <ne**@CsabaGabo r.com> wrote in message
news:bj******** @dispatch.conce ntric.net...
<snip>
... there is a two pixel difference! The observed behaviour
is that when you approach the border from the outside, it
always works but going from the inside to the outside of the
table it fails on two borders because of the two pixel
difference. Can anyone spot how to fix this problem up?
Thanks for any tips,

<snip>

Your problem is with the position of the 0,0 co-ordinate for mouse
positions. On Opera, Mozilla and other non-IE browsers the 0,0 position
is the top left of the HTML page within the viewport. On IE the 0,0
position is outside the inner border (or the top left of the inner
border). A difference of 2 pixels by default. Unfortunately, on IE,
chaining the offsetTop/Left values produces co-ordinates with a 0,0
position in the top-left corner of the viewport (just inside the inner
border. That is equivalent to the situation on Mozilla, etc.

The solution that I use is to adjust the mouse co-ordinates by the
clientTop/Left values for the root element (body or documentElement
depending on compatMode). I use mouse position reading scripts such as
the following:-

var MoveFollow = (function(){
var theOne = null;
var XY = {x:0,y:0};
var readScroll = {scrollTop:0,sc rollLeft:0,
clientLeft:0,cl ientTop:0};
var eventInited = false;
var posReadX = 'pageX';
var posReadY = 'pageY';
function mm(e){
e = e||event;
XY.x = e[posReadX];
XY.y = e[posReadY];
};
function initEvent(ev){
ev = ev||event;
if(ev){
if(typeof ev.pageX != 'number'){
posReadX = 'clientX';
posReadY = 'clientY';
if(typeof opera != 'object'){
if((document.co mpatMode)&&
(document.compa tMode == 'CSS1Compat')&&
(document.docum entElement)){
readScroll = document.docume ntElement;
}else if(document.bod y){
readScroll = document.body;
}
}
}
setUpOnMouse(mm );
mm(ev);
eventInited = true;
}else{
setUpOnMouse(in itEvent);
}
};
function setUpOnMouse(f) {
if(document.onm ousemove != f){
document.onmous emove = f;
if((document.ca ptureEvents)&&
(document.layer s)&&(typeof Layer == 'function')){
document.captur eEvents(Event.M OUSEMOVE);
}
}
};
return (function(ev){
if(!eventInited )initEvent(ev);
if(theOne)retur n theOne;
this.getPageX = function(){
return ((readScroll.sc rollLeft||0) -
(readScroll.cli entLeft||0) + XY.x);
};
this.getPageY = function(){
return ((readScroll.sc rollTop||0) -
(readScroll.cli entTop||0) + XY.y);
};
this.getPageXY = function(){
return {x:this.getPage X(),y:this.getP ageY()};
};
this.upDate = function(ev){
mm(ev);
}
theOne = this;
});
})(); //simultaneously define and call (one-off)!

This code is a mouse position following object that uses the
document.onmous emove handler to track the position of the mouse. The
object is created with - new MoveFollow() - or new
MoveFollow(mous eEvent) - (if a mouse event is available at construction
time, onload,etc events are not suitable as they do not include mouse
properties on Mozilla, for example. It is probably better not to pass an
event to the constructor as it will compensate by setting up based on
the first mousemove event received). The class is a singleton so no
matter how many examples are created with the - new - keyword only one
object is instantiated and all subsequent calls return references to
that object. Given:-

var readMousePositi on = new MoveFollow();

- the position of the mouse (at the time of the last mouse move event)
can be read as:-

var X = readMousePositi on.getPageX();
var Y = readMousePositi on.getPageY();

Part of the point of this code is that the mouse position reading
function is very light weight, which is necessary as mousemove events
are _very_ frequent and code that reacts to them should be quick.

The important adjustment that corrects the 2 pixel discrepancy on IE is
subtracting the root element clientTop/Left values, which is only done
in the getpageX/Y functions.

Richard.
Jul 20 '05 #2
Richard,

Thanks very much for your explanation and functions.
I have updated my code, and it is now working in all the
browsers that I cited earlier.

There is a another point that I have to confess that I
missed. My getRect function was incorrect (oops) as
written and that is why Opera and Netscape were messing
up. I was forgetting to subtract one for the Right and Bottom
values in getRect and that extra pixel made the difference.

Now I am ready to move on to the next step of identifying
which cells the mouse is between if it's not over a single cell.

Thanks again for your reply, Richard,
Csaba

function getRect(elem) {
// return absolute position of elem
// (Left, Top, Right, Bottom) in page
var i;
if (typeof(elem.my Rect)!="undefin ed") return elem.myRect;
var myRect = Array(elem.offs etLeft, elem.offsetTop,
elem.offsetLeft + elem.offsetWidt h-1,
elem.offsetTop + elem.offsetHeig ht-1)
// see Richard's code for definition of readScroll
if (!elem.offsetPa rent) {
var xAdjust = (window.readScr oll.clientLeft| |0)-(window.readScr oll.scrollLeft| |0)
var yAdjust = (window.readScr oll.clientTop|| 0)-(window.readScr oll.scrollTop|| 0)
for (i=0;i<4;i++) myRect[i] += (i%2)?yAdjust:x Adjust;
return myRect;
}
newRect = getRect(elem.of fsetParent)
for (i=0;i<4;i++) myRect[i] = myRect[i] + newRect[i % 2];
return myRect;
}
"Richard Cornford" <Ri*****@litote s.demon.co.uk> wrote in message news:bj******** ***********@new s.demon.co.uk.. .
"Csaba2000" <ne**@CsabaGabo r.com> wrote in message
news:bj******** @dispatch.conce ntric.net...
<snip>
... there is a two pixel difference! The observed behaviour
is that when you approach the border from the outside, it
always works but going from the inside to the outside of the
table it fails on two borders because of the two pixel
difference.

Can anyone spot how to fix this problem up?
Thanks for any tips,

<snip>

Your problem is with the position of the 0,0 co-ordinate for mouse
positions. On Opera, Mozilla and other non-IE browsers the 0,0 position
is the top left of the HTML page within the viewport. On IE the 0,0
position is outside the inner border (or the top left of the inner
border). A difference of 2 pixels by default. Unfortunately, on IE,
chaining the offsetTop/Left values produces co-ordinates with a 0,0
position in the top-left corner of the viewport (just inside the inner
border. That is equivalent to the situation on Mozilla, etc.

The solution that I use is to adjust the mouse co-ordinates by the
clientTop/Left values for the root element (body or documentElement
depending on compatMode). I use mouse position reading scripts such as
the following:-

var MoveFollow = (function(){
var theOne = null;
var XY = {x:0,y:0};
var readScroll = {scrollTop:0,sc rollLeft:0,
clientLeft:0,cl ientTop:0};
var eventInited = false;
var posReadX = 'pageX';
var posReadY = 'pageY';
function mm(e){
e = e||event;
XY.x = e[posReadX];
XY.y = e[posReadY];
};
function initEvent(ev){
ev = ev||event;
if(ev){
if(typeof ev.pageX != 'number'){
posReadX = 'clientX';
posReadY = 'clientY';
if(typeof opera != 'object'){
if((document.co mpatMode)&&
(document.compa tMode == 'CSS1Compat')&&
(document.docum entElement)){
readScroll = document.docume ntElement;
}else if(document.bod y){
readScroll = document.body;
}
}
}
setUpOnMouse(mm );
mm(ev);
eventInited = true;
}else{
setUpOnMouse(in itEvent);
}
};
function setUpOnMouse(f) {
if(document.onm ousemove != f){
document.onmous emove = f;
if((document.ca ptureEvents)&&
(document.layer s)&&(typeof Layer == 'function')){
document.captur eEvents(Event.M OUSEMOVE);
}
}
};
return (function(ev){
if(!eventInited )initEvent(ev);
if(theOne)retur n theOne;
this.getPageX = function(){
return ((readScroll.sc rollLeft||0) -
(readScroll.cli entLeft||0) + XY.x);
};
this.getPageY = function(){
return ((readScroll.sc rollTop||0) -
(readScroll.cli entTop||0) + XY.y);
};
this.getPageXY = function(){
return {x:this.getPage X(),y:this.getP ageY()};
};
this.upDate = function(ev){
mm(ev);
}
theOne = this;
});
})(); //simultaneously define and call (one-off)!

This code is a mouse position following object that uses the
document.onmous emove handler to track the position of the mouse. The
object is created with - new MoveFollow() - or new
MoveFollow(mous eEvent) - (if a mouse event is available at construction
time, onload,etc events are not suitable as they do not include mouse
properties on Mozilla, for example. It is probably better not to pass an
event to the constructor as it will compensate by setting up based on
the first mousemove event received). The class is a singleton so no
matter how many examples are created with the - new - keyword only one
object is instantiated and all subsequent calls return references to
that object. Given:-

var readMousePositi on = new MoveFollow();

- the position of the mouse (at the time of the last mouse move event)
can be read as:-

var X = readMousePositi on.getPageX();
var Y = readMousePositi on.getPageY();

Part of the point of this code is that the mouse position reading
function is very light weight, which is necessary as mousemove events
are _very_ frequent and code that reacts to them should be quick.

The important adjustment that corrects the 2 pixel discrepancy on IE is
subtracting the root element clientTop/Left values, which is only done
in the getpageX/Y functions.

Richard.

Jul 20 '05 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
2340
by: Tom Szabo | last post by:
Hi, Just wondering if there are any disadvantage in absolute positioning controls on a page? In example instead of putting the text fields into a table to align properly, one would absolute position them. I understand the issue with resize, that is not a problem.
7
6309
by: Griff Miller | last post by:
Please see http://home.houston.rr.com/gmiller15/css/vertprob.html . In mozilla 1.6/1.7 it looks the way I want it, with a thin separation between the two boxes. In IE6, the two boxes touch, which is not what I want. Is there a way to get IE6 to do it the mozilla way? Thanks! Griff
4
4619
by: mike eli | last post by:
Hi, I have several absolute positioned elements inside an absolute positioned DIV. I would like one of the nested elements to have a dynamic width. I set it's left and right attributes to 5, so the the element should have a width = parentWidth - 10; This is the desired behaviour, but it won't work. I still have to specify a width or the element has a width of 0. Setting the width to '100%' doesn't give me the desired effect; it takes...
4
2109
by: Alan Silver | last post by:
Hello, Having been a light reader of this ng for a few months now (after several years absence), I have noticed that absolute positioning seems to be considered a Very Bad Thing around here. Generally, when someone posts a question about a design that uses it, they are told not to. Now, in my ignorance, I don't see what's wrong with it, when used sensibly. Let me say straight off that I am *not* talking about trying to produce...
3
2231
by: horusprim | last post by:
Is there a CSS absolute positioning rendering bug in FF1.02 and IE 6? I have been experimenting with precision absolute positioning in CSS. The following test content was used in the experiment: "This sentence is to be about nine words long. I hope this test suite works. Mary had a little lamb and its fleece was white as snow." Next a macro was used to divide the content into equal sentence fragment spans of the 12 characters each...
2
3164
by: nonsensitor | last post by:
I'm just learning xhtml & css, primarily from westciv's online tutorials and css guide. I've run into a couple of problems with a page I'm developing that I can't figure out. The first problem is that I would like to display some text on top of an image within the header. I've tried using absolute positioning to specify where the phone number should appear in relation to the parent div (#header). However the text appears to be positioned in...
6
2917
by: Mark | last post by:
hi, i'm trying to position something in the top right corner of a container, but i can't seem to figure out how to get it working. here's the html <div class='thumb'><a href='image.jpg'><img src='photos/thumbs/ bigsmile.jpg'></a><a class='del' href='?p=gallery&del=2'>x</a></div> where 'thumb' is my container, and 'del' should be aligned to the top right. here's the css
20
2817
by: mehstg1319 | last post by:
Hi there Not sure if anyone can help me, I am working on a site for my university, and am having a bit of trouble with css positioning. I am very new to css and do not know very much about it. Here is the link: http://homepages.feis.herts.ac.uk/~bp6ar/bus_intel/matrix/matrix.html Basically, the problem is that the ticks on the grid look perfectly
14
3314
by: Fistro | last post by:
I'm trying to find a design that would allow me to build web pages without having to worry about compatibility issues (not too much, in any case,,,) I've came across this CSS layout technique: http://alistapart.com/articles/fauxabsolutepositioning It calculates the left offset from a fixed position, as opposed to calculating it from the right edge of the preceding element by using a combination of position: relative, left: 100% and a...
0
9333
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10107
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9945
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9900
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9765
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6599
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5361
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3863
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2733
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.