1

Thanks to suggestions I received here, I fixed some problems with my code and now I have:

window.onload = function(){

    var tooltip = $( '<div id="tooltip">' ).appendTo( 'body' )[0];

$( 'img' ).
    each(function () {
        var pos = $( this ).position(),
            top = pos.top,
            left = pos.left,
            width = $( this ).width(),
            height = $( this ).height(); 
        $( this ).
            mousemove(function ( e ) {
                var x = e.pageX - left,
                    y = e.pageY - top;

                $( tooltip ).html( 'x = ' + x + '<br/>y = ' + y ).css({
                    left: e.clientX + 10,
                    top: e.clientY + 10
                }).show();
            }).
            mouseleave(function () {
                $( tooltip ).hide();
            }); 

    });

};

Unfortunately, the Y coordinate is not an integer number! See the picture:

enter image description here

The difference vs. what it should be is constant: -0.42. It varies from -0.42 on the upper edge of the photo to 1198.58 at the lower edge. (picture height is 1200).

I could definitely round it up and solve the problem, but it's not a clean solution. I'd like to get it right from the beginning.

This is the CSS:

body { font:13px/1.4 Arial, sans-serif; margin:50px; background:gray; }
#tooltip { text-align:left; background:black; color:white; padding:3px 0; position:fixed; display:none; white-space:nowrap; }

And this is the HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<link href="style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="javascript.js"></script></head>
</head>

<body>


<div id="content">
<h1>JS test</h1>
<img class="coords" src = "pic.jpg">

<p>Paragraph between images</p>


<img class="coords" src = "pic.jpg">
</div>

</body>
</html

Thanks a lot for your help!

Davide

Community
  • 1
  • 1
Davide
  • 87
  • 13
  • 1
    The issue is probably that the position of the `` element itself involves non-whole numbers. What does its CSS look like? – Pointy Jun 28 '12 at 13:30
  • You can't have a half pixel! @Pointy – 11684 Jun 28 '12 at 13:44
  • @11684 tell that to Chrome and Safari. – Pointy Jun 28 '12 at 13:46
  • Hi Pointy, I added the CSS. Thanks for your comment! – Davide Jun 28 '12 at 13:49
  • @Pointy I think that those are not the real pixels, but the percents to pixels. So, for example, you have a screen of 1068px wide (I don't know if that's possible, but it's just an example) and an element 90% wide. Then Chrome says the element is `1068 x 0.9 = 96.12px`. – 11684 Jun 28 '12 at 13:54
  • Just to say: "right from the beginning" IS the floating point number... you want to get the position as integer while it's actually not, so the cleaner solution would be to round() it afterwards... – Simon Jun 28 '12 at 13:56
  • http://stackoverflow.com/questions/1458633/elegant-workaround-for-javascript-floating-point-number-problem – Simon Jun 28 '12 at 14:06
  • @11684 right; I understand of course that a pixel is a pixel. The browsers (well WebKit anyway) just keep track of the fractional parts. It's significant if you think of devices with "retina" displays, where there are "logical" pixels and "real" pixels. – Pointy Jun 28 '12 at 14:16
  • 2
    This is also important when you start using zoom. A 'round' to whole pixels would make it impossible to precisely position an element. – Willem Mulder Jun 28 '12 at 14:33
  • @Pointy Yes, I noticed. IPhone 4 uses points instead of pixels. Very confusing if you don't know that and seeing someone drawing a line 5.6 long. – 11684 Jun 28 '12 at 15:11
  • Thanks Willem! I actually experienced that already... If I zoom with Ctrl++ or Ctrl+MouseWheel, I get negative coordinates (X=-30, Y=50, etc...) – Davide Jun 28 '12 at 23:58

1 Answers1

3

To answer the question in the title: Top or Left can in CSS be defined as percentages or 'em' etc. jQuery however always returns pixels, so this might be the cause of getting a floating point number instead of an integer when jQuery converts e.g. a percentage to pixels.

The second question, why it is always -0.42, I don't know for sure without having a jsFiddle or something similar. Edit: but you are using .position() which gives the position relative to the parent, while e.pageX is relative to the page. Thus, e.pageY can be 0.42 at the top of the image (relative to the top of the page) while image.position().top can be 0 (relative to the parent), so that the resulting x becomes -0.42.

You probably want to use .offset(), which is relative to the page! See http://api.jquery.com/offset/

Willem Mulder
  • 12,974
  • 3
  • 37
  • 62
  • 1
    I get integer values from your code in this [jsFiddle](http://jsfiddle.net/styson/mRHnN/) example. What other factors are in play to determine the img position? – Sam Tyson Jun 28 '12 at 13:34
  • 1
    See my updated answer. Img position is relative to the position of the parent, not relative to the position of the page! – Willem Mulder Jun 28 '12 at 13:43
  • Hi Willem! Thanks a lot for your reply! I replaced "position()" with "offset()" in my code, as you suggested, but it still gives me -0.42 to 1198.58. – Davide Jun 28 '12 at 13:54
  • Could you create a jsFiddle recreating the problem? – Willem Mulder Jun 28 '12 at 14:10
  • Hi Sam, I tried your jsFiddle, thanks for creating one! I added my HTML and CSS to it, but it still gives integer values. I guess the rendering engine used by jsFiddle is simpler than most browsers. On Chrome, I get -0.42 vs the correct value, on Firefox I get +0.18... Pretty weird. Thanks again! – Davide Jun 28 '12 at 14:11
  • So what about padding/borders/margin set on the document? Or maybe a border on the image? – Willem Mulder Jun 28 '12 at 14:14
  • I managed to create a jsFiddle that shows the problem!!!!!! http://jsfiddle.net/x5jG4/1/ – Davide Jun 28 '12 at 14:36
  • Here in Chrome, it just works and only returns integers... It's maybe something with your browser setup...? Plugins? Zoom settings? – Willem Mulder Jun 28 '12 at 14:51
  • Chrome here too... I actually packaged my JS as a Chrome extension, disabled all other extensions, then opened my Facebook page... I clicked Ctrl+0 to make sure no zoom was on the page. On some photos, both X and Y are integer, on some other photos X is integer but Y is not, on some other photos it is the opposite. I can't believe how a tiny simple piece of code like that can create such a mess. Thanks for the continued help! – Davide Jun 28 '12 at 15:12