3

Is this possible? I'm trying to find the x and y coordinates of the element in relation to the browser.

var position = $(this).position();
    x = position.left;
    y = position.right;

Doesn't work.

Is there any way to do this?

http://adamsaewitz.com/housing/
highlight the blue room 070

switz
  • 24,384
  • 25
  • 76
  • 101

3 Answers3

7

The problem lies in the fact that you are accessing the top/left of an area element.

The area element is not positioned where its coords say. This is handled behind the scenes by the dom/browser.

So you need to find the image that the area relates to and grab its offset.

var imgId = $(this).closest('map').attr('name');
var imgPos = $('#' + imgId).offset();

Then, you grab the coords attribute of the area and split it to get left/top/width and use those to pinpoint the location inside the image.

var coords = $(this).attr('coords').split(',');
var box = {
            left: parseInt(coords[0],10),
            top: parseInt(coords[1],10),
            width:  parseInt(coords[2],10)-parseInt(coords[0],10),
            height:  parseInt(coords[3],10)-parseInt(coords[1],10)
            };

Take into consideration the width/height of the info box that appears (and since you animate it, take that into consideration as well) and you get to

x = imgPos.left + box.left + box.width/2 - 65; // 65 is the info width/2
y = imgPos.top + box.top -20 -160 -1; // 20 is the animation, 160 is the info height, 1 is a safe distance from the top

demo: http://www.jsfiddle.net/XBjwN/

Gabriele Petrioli
  • 191,379
  • 34
  • 261
  • 317
  • 1
    There's no need for the overhead here, just giving the parent a `relative` position takes care of the offset in a much cleaner way, see the comments on my answer for links to demos of this. – Nick Craver Dec 25 '10 at 10:45
  • Good point @Nick. In the present case, the relative `#content` indeed solves the issue. But if there was any other content inside the `#content` (*and the name implies there might be*) and before the image it would not. Same goes for the map object to be defined somewhere else.. – Gabriele Petrioli Dec 25 '10 at 10:56
  • true, valid concerns, but I'd *still* go for the `relative` option, if a `
    ` is needed around each then I still find it a much cleaner/more versatile approach, as you have a consistent `.closest()` accessibly parent to put your elements in as well.
    – Nick Craver Dec 25 '10 at 11:00
  • @nick, agreed! It is cleaner your way. (*the `map` used in the `.closest()`, though, is obligatory for the area elements*) – Gabriele Petrioli Dec 25 '10 at 20:34
6

Edit for updated question: Since you're using <area> it's a different story, and fetching from the coords attribute is much easier, like this:

var position = $(this).attr('coords').split(',');
x = +position[0] - 50;
y = +position[1] - 170;

The offsets are just to account for the hard-coded width/height of the tooltip itself. In addition to the above, you want to use top and left rather than margin-top and margin-left. Also to account for the #content <div>'s position in the page, give it a relative position for the tooltip to sit in, like this:

#content { position: relative; }

Then...instead of .after(), use .append() so it gets added inside that parent.

You can test the result here.


For original question:
The object .position() returns has top and left properties...but you want .offset() here anyway (it's relative to the document, where .position() is relative to the offset parent), so it should look like this:

var position = $(this).offset(),
    x = position.left,
    y = position.top; //not right!

Or this:

var position = $(this).offset();
var x = position.left;
var y = position.top;

...but without a single var comma-separated statement, or a var on each line, you're also creating (or trying to) global variables, which will blow up in IE.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • 1
    Strange use of the comma operator. – Tomas Dec 25 '10 at 10:01
  • Haha, wow that's a sign it's late. But that still doesn't work, sorry. – switz Dec 25 '10 at 10:01
  • @Switz - what's not working? Note you want `.offset()` not `.position()`, which is relative to the *parent*, not the `document`. – Nick Craver Dec 25 '10 at 10:02
  • I'm using global operators. The instances are created earlier. – switz Dec 25 '10 at 10:02
  • @Tomas - how so? it's just a single `var` declaration, standard JS :) – Nick Craver Dec 25 '10 at 10:02
  • I've posted the example up in the main post, please take a look at the code. – switz Dec 25 '10 at 10:03
  • @Switz - one sec, taking a look – Nick Craver Dec 25 '10 at 10:10
  • @Switz - have you considered grabbing it from the `coords` attribute you already have, like this? http://www.jsfiddle.net/nick_craver/YnPsb/ – Nick Craver Dec 25 '10 at 10:16
  • Yes, but then if the window is not the size of the image, it doesn't line up properly. I'm sure there's a way to get around it, but I wanted to avoid it. I have an idea. gimmie a sec, thanks – switz Dec 25 '10 at 10:22
  • @Switz - if you insert the content in a relative parent that contains both...the image//window relation doesn't matter, since it's in relation to the area that contains the image, if you notice I changed it to `.append()` rather than `.after()` when creating the tooltip. – Nick Craver Dec 25 '10 at 10:23
  • I did that and it's still not working. Updated jsfiddle: http://www.jsfiddle.net/YnPsb/2/ if you resize the browser it changes its location, idk why. – switz Dec 25 '10 at 10:28
  • 1
    @Switz, This should work as you want it .. http://www.jsfiddle.net/YnPsb/5/ You need to get the info from the coords, but at the same time adjust for the image (*they point to*) offset. Additionally you need to adjust for the width/height of the info box as well as the area width. – Gabriele Petrioli Dec 25 '10 at 10:32
  • That looks great! Very intuitive. Make it an answer and I'll give you credit. Thanks a bunch! – switz Dec 25 '10 at 10:34
  • @Switz - you just need to give `#content` that relative position I mentioned in the last comment: `#content { position: relative; }`, check it out here: http://www.jsfiddle.net/nick_craver/YnPsb/6/ – Nick Craver Dec 25 '10 at 10:44
0
$(document).ready(function () {
            $('map').imageMapResize();
            $('area').hover(function () {
                $('.imgpopover').css({ "display": "block", "top": $(this).attr("coords").split(',')[1]+"px", "left": $(this).attr("coords").split(',')[0]+"px" })
                $('.imgpopover label').text($(this).attr("title"))
            }, )
        });