[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 736
  • Last Modified:

javascript cursor and image position problem

I want to get the current pixel position of an onclick event on an image. I have the following html document:
<html>
<head>
<title>test pointer</title>
<script language=javascript>
function savexy(e) {
iy = document.getElementById("image").offsetTop;
ix = document.getElementById("image").offsetLeft;
var IE = document.all?true:false;
if (IE) {
tempX = event.clientX + document.body.scrollLeft-2;
tempY = event.clientY + document.body.scrollTop-2;
}
else {  // grab the x-y pos.s if browser is NS
tempX = e.pageX;
tempY = e.pageY;
}  
document.form1.Uxval.value = tempX-document.form1.xval.value;
document.form1.Uyval.value = tempY-document.form1.yval.value;
}
function show(e) {
document.form1.yval.value = document.getElementById("image").offsetTop;
document.form1.xval.value = document.getElementById("image").offsetLeft;
var IE = document.all?true:false;
if (IE) {
tempX = event.clientX + document.body.scrollLeft-2;
tempY = event.clientY + document.body.scrollTop-2;
}
else {  // grab the x-y pos.s if browser is NS
tempX = e.pageX;
tempY = e.pageY;
}  
document.form1.Cxval.value = tempX;
document.form1.Cyval.value = tempY;
document.form1.Ixval.value = tempX-document.form1.xval.value;
document.form1.Iyval.value = tempY-document.form1.yval.value;
document.getElementById("coords").style.top = tempY+20;
document.getElementById("coords").style.left = tempX+20;
document.getElementById("coords").innerHTML =

document.form1.Ixval.value+','+document.form1.Iyval.value;
}
function vistog(stat){document.getElementById("coords").style.visibility = stat}
</script>
<script type="text/javascript">
 document.onmousemove=show;
</script>
</head><body>
<form name=form1>
<br>this si so it can scroll
<br>this si so it can scroll<br>this si so it can <br>this a test for cursor<br>
positioning<br>
<img id="image" src="/images/greeting_cards_sample_pic.jpg" onmouseover="vistog('visible')"

onmouseout="vistog('hidden')" onclick="savexy(event)" border=0>
<br>
x <input type=text name=xval>, y <input type=text name=yval>
<br>Cx <input type=text name=Cxval>, Cy <input type=text name=Cyval>
<br>Ix <input type=text name=Ixval>, Iy <input type=text name=Iyval>
<br>Ux <input type=text name=Uxval>, Uy <input type=text name=Uyval>
<br>this si so it can scroll
<br>this si so it can scroll<br>this si so it can

scrollkasdkasdksmadhfashdhdddddhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh

hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk

kkkkkkkkkkhhhhhhhhhhhhh
<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so

it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can

scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this

si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can

scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this

si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can

scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this

si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can

scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this

si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can

scroll<br>this si so it can scroll<br>this si so it can scroll<br>this si so it can scroll<br>this

si so it can scroll<br>this si so it can scroll
<div id="coords"

style="visibility:hidden;position:absolute;left:50px;top:240px;background-color:white;border:black

solid 1px;padding:1px 1px 1px 1px" >test div</div>
</form>
</body>
</html>
put anything in for the graphic. When I use ie7, it gives me an image location of 10,53, but the cursor when I hit the corner is 12,55. They are both offset by 2 pixels. If I use firefox, I get 8,48 and when I hit the corner, the cursor is at 8,48. 0 offset and I would assume correct. Can someone tell me what is going on here? I put in an adjustment of 2 pixels if ie, and that works, but is it the same for all ie browsers? It seems that the pointer position is reflecting the border and the tab frame in ie, but the image position is not. Do I need to use another reference?
0
troyd1
Asked:
troyd1
  • 9
  • 3
1 Solution
 
netsmithcentralCommented:
I'm not sure exactly what you're looking for here.  Do you want the coordinates of the mouse on the screen (relative to your page)?  Or do you want the coordinates of an element (eg a DIV) on the page relative to the document?  I'm assuming based on the code you're looking for the X, Y mouse coordinates on screen.

<script type="text/javascript">
document.onclick = getMouseCoords;

function getMouseCoords(e) {
    if(!e) var e = window.event;

    var x = (e.pageX) ? e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    var y = (e.pageY) ? e.pageY : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;

    alert("X Coordinate: " + x +"\n" +
            "Y Coordinate: " + y);
}
</script>


If what you want is the position of the element (the image for instance) you'll want to use this script:

<script type="text/javascript">
document.onclick = getElementCoords;

function getElementCoords(e) {
    if(!e) var e = window.event;

    var obj = (e.srcElement) ? e.srcElement : e.target;

    var x = obj.offsetLeft;
    var y = obj.offsetTop;

    while(obj = obj.offsetParent) {
        x += obj.offsetLeft;
        y += obj.offsetTop;
    }

    alert("X Coordinate: " + x +"\n" +
            "Y Coordinate: " + y);
}
</script>
0
 
troyd1Author Commented:
I condensed the problem. I took your basic code, but cannot get it to work correctly. It does not seem to be adding the offsetparent top and left in the loop. I put in an alert after the while and it says they are both 0. My initial problem is prevelent here. If you move your mouse from the top, I get 65 for pointer top position and 63 for the element top position.
Here is the code:
<html>
<head>
<title>test pointer</title>
<script language=javascript>
function update(e){
 if(!e) var e = window.event;
 var x = (e.pageX) ? e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
 var y = (e.pageY) ? e.pageY : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
 document.form1.xval.value = x;
 document.form1.yval.value = y;
 var obj = document.getElementById("element");
 var xE = obj.offsetLeft;
 var yE = obj.offsetTop;
 while(obj = obj.offsetParent) {
  xE += obj.offsetLeft;
  yE += obj.offsetTop;
 }
 document.form1.Exval.value = xE;
 document.form1.Eyval.value = yE;
return;
}
</SCRIPT>
</head><body>
<form name=form1>
xP <input type=text name=xval>, yP <input type=text name=yval>
<br>xE <input type=text name=Exval>, yE <input type=text name=Eyval>
<CENTER><DIV id="element" onmouseover="update(event)">somedata</div></center>
</form>
</body>
</html>
You can try it at www.premierecolors.com/testpos.html
0
 
troyd1Author Commented:
Note: the code does not seem to take the offsetleft of the center tag.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
troyd1Author Commented:
Here is another example of the offset by 2 pixels in ie7(not sure about other releases) problem. It works fine in firefox. If you drag from the left or top the cursor position will indicate a position of 2 and the div of 0. I set the div at 0,0. I believe it is taking the tabbed frame and counting that in the cursor position, but not in the element offset.
http://www.premierecolors.com/TESTPOs2.HTML

0
 
netsmithcentralCommented:
These "problems" (except the IE7 one) are by design.  First, you have to understand how offsetLeft / Top work.  These two numbers give you the pixel position of an element on your page RELATIVE TO THEIR offsetParent.  So for a DIV whose an immediate child of BODY, the offsetParent is BODY.  BODY has an offsetLeft and Top of 0.

If you have an element that's deeply embedded in other elements (maybe a DIV in a TABLE in a DIV), you'll be depending on the offsetParent loop to add all the offsets and give you a position RELATIVE TO THE DOCUMENT (thats what we really care about anyway, right?).

As for the CENTER tag, its offset is not the leftmost position of the centered data.  It's the leftmost point of the entire "row" that the data is centered across.

As for IE7, try moving your DIV to arbitrary coordinates (100, 100 eg) and testing it there.  Also try mousing over the DIV at different speeds and see how that changes the coordinate data you get.  You'll see that you end up with all kinds of different answers.  This is because the mouseover event doesn't fire "immediately" and the coordinates it has are saved from when it fires.  AFAIK, there is no way to guarantee that the event fires at the exact moment you mouse over the DIV (and therefore guarantee the "correct" data).

Here's some test code for you:
<html>
<head>
<script type="text/javascript">
window.onload = function() {
   document.getElementById("theDiv").onmouseover = getMouseCoords;
};

function getMouseCoords(e) {
    if(!e) var e = window.event;

    var x = (e.pageX) ? e.pageX : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    var y = (e.pageY) ? e.pageY : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;

    alert("X Coordinate: " + x +"\n" +
            "Y Coordinate: " + y);
}
</script>
</head>
<body>
<div style="position: absolute; top: 100; left: 100; width: 300; height: 300; background-color: rgb(255, 0, 0);" id="theDiv"></div>
</body>
</html>
0
 
troyd1Author Commented:
2 questions. If you look at testpos2.html. I have placed that div at 0,0. If I drag down slowly, it will fire when it touches the top of the div. The div is positioned at 0. The cursor always shows 2 in ie. If you do the same thing in firefox, it always shows 0 for the pointer. It works the same from the left. If I add mousemove code, you can see the position changing above and to the left of the div. See this example:
http://www.premierecolors.com/TESTPOs3.HTML
I added an onmousemove to continuously update the mouse coordinates. If you start at the top or left, you can see the cursor o from 0 to 1 and then when it hits 2, it fire the mouseover and shows the div coordinates. The div is positioned at 0,0 the div coords should show the first time the pointer position changes. I think there is another offset that is in ie7 that is 2 pixels that is not being accounted for. It works fine in firefox.

My other question is: Is there any way to know what the actual position of an element is? This part does indeed work the same in both browsers.
0
 
troyd1Author Commented:
Also, I thought maybe it had to do with tabbed browsing, but when I turned it off, it remained the same.

0
 
troyd1Author Commented:
The second part of the question is answered. I did not realize the div would go across the whole screen until I put a border on it. I put a height and width on it and centered it and it gave the offset correctly. The 2 pixel offset is still a problem though.
0
 
troyd1Author Commented:
Sorry for the missinformation. In my comments 3 posts ago, it should have said testpos3.html and not testpos2.html. Been a long few days.....sorry.
0
 
troyd1Author Commented:
ignore the last post, sorry again.
0
 
troyd1Author Commented:
This thread got messy and convoluted. I am going to award points as it helped me get closer. I am going to repost a more concise example.
0
 
netsmithcentralCommented:
Sorry it took so long to post in this thread again.  Here's some more info for you.

You can know the absolute position of an element on the page (relative to the document, not the window) using the getElementCoords function I provided you.  This will work in any browser that supports offsetParent.  You can use the following function to test for offsetParent:

function isOffsetParentCompatible(){
    var obj = document.getElementsByTagName("*")[0];
    if(obj.offsetParent) return true;
    else return false;
}


As for the slight mouse position offset in IE, my best bet is still the event firing issue.  Is there a reason you need to know the coordinates onmousemove / onmouseover (instead of onclick for example)?  Maybe we can help you come up with an alternate solution.

Remember, there are NO offsets in relation to the mouse position (that's the element position), just an x and y coordinate.  The closest thing to an "offset" with relation to mouse coordinates is the scroll distance.  Some browsers will tell you the mouse coordinates with relation to the window NOT the document.  Because we want to know this in relation to the document (otherwise its useless), we have to add the "scrollTop" (distance the user has scrolled down the page in pixels) and "scrollLeft" (distance the user has scrolled across the page in pixels).
0
 
alexcohnCommented:
Actually, there is some strange (2,2) offset for the mouse event coordinates in IE 6, 7. Try to open IE in fullscreen (press F11) and use the following test HTML:

<html>
<body style="margin:0px; padding:0px; border:0px; ">
<div onmousedown="alert(event.clientX +','+ event.clientY)" style="background-color: blue; width:100px; height:100px;"></div>
</body>
</html>

You can see that the left-most blue pixel (it is on the verge of the screen) reports clientX as 2. I used mousedown instead of mouseover because it's easier to control; but if you replace the event with mouseover, you will see the same answer.
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 9
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now