Mouse position in both fixed and relative positioning

Discussion in 'Javascript' started by Nikolai Prokoschenko, May 17, 2011.

  1. Hello,

    this question is connected to AmCharts (http://amcharts.com/javascript/) but it's not *about* AmCharts, it's just the context of the problem I'm having. (NB: AmCharts' API and general code provide enough material for several pages of flaming ;))

    AmCharts, like almost every charting solution, has a concept of a "balloon", those are small popups which follow the mouse cursor and show some more or less relevant information about the chart item under this cursor. They use some browser-detecting code to find mouse's position for these balloons, which failed for me on several occasions, so I monkey-patched that code by the code provided by Peter-Paul Koch at http://www.quirksmode.org/js/events_properties.html. For the record, here is his code:

    function doSomething(e) {
    var posx = 0;
    var posy = 0;
    if (!e) var e = window.event;
    if (e.pageX || e.pageY) {
    posx = e.pageX;
    posy = e.pageY;
    }
    else if (e.clientX || e.clientY) {
    posx = e.clientX + document.body.scrollLeft
    + document.documentElement.scrollLeft;
    posy = e.clientY + document.body.scrollTop
    + document.documentElement.scrollTop;
    }
    // posx and posy contain the mouse position relative to the document
    // Do something with this information
    }

    This works splendidly in most cases, but as you can see, it's relative to the document, which means it won't work properly for fixed elements (e.g., lightboxed charts) when the document is scrolled. It turns out, AmCharts' original code also fails on fixed elements. By removing the scrolling position from the calculations, I'd probably get correct values for fixed elements, but instead the values would be broken for elements inside the document flow. Unfortunately, in my case, it has to work for both types of elements :(

    My idea was to get the element under cursor, go all the way up in the DOM tree to check whether there are any elements with fixed positioning and calculate the cursor position relative to the scroll position of that element instead of documentElement's. However, I'm not sure whether this is correct or even doable.

    So the actual question is: how do I find the correct mouse position for both fixed and relatively positioned elements? Note: I don't need complete code, some hints and directions would suffice for a start.

    Thanks.

    Nikolai.
    Nikolai Prokoschenko, May 17, 2011
    #1
    1. Advertising

  2. On Tue, 17 May 2011 04:51:46 -0700 (PDT), Nikolai Prokoschenko
    <> wrote:

    >Hello,
    >
    >this question is connected to AmCharts (http://amcharts.com/javascript/) but it's not *about* AmCharts, it's just the context of the problem I'm having. (NB: AmCharts' API and general code provide enough material for several pages of flaming ;))
    >
    >AmCharts, like almost every charting solution, has a concept of a "balloon", those are small popups which follow the mouse cursor and show some more or less relevant information about the chart item under this cursor. They use some browser-detecting code to find mouse's position for these balloons, which failed for me on several occasions, so I monkey-patched that code by the code provided by Peter-Paul Koch at http://www.quirksmode.org/js/events_properties.html. For the record, here is his code:
    >
    >function doSomething(e) {
    > var posx = 0;
    > var posy = 0;
    > if (!e) var e = window.event;
    > if (e.pageX || e.pageY) {
    > posx = e.pageX;
    > posy = e.pageY;
    > }
    > else if (e.clientX || e.clientY) {
    > posx = e.clientX + document.body.scrollLeft
    > + document.documentElement.scrollLeft;
    > posy = e.clientY + document.body.scrollTop
    > + document.documentElement.scrollTop;
    > }
    > // posx and posy contain the mouse position relative to the document
    > // Do something with this information
    >}
    >
    >This works splendidly in most cases, but as you can see, it's relative to the document, which means it won't work properly for fixed elements (e.g., lightboxed charts) when the document is scrolled. It turns out, AmCharts' original code also fails on fixed elements. By removing the scrolling position from the calculations, I'd probably get correct values for fixed elements, but instead the values would be broken for elements inside the document flow. Unfortunately, in my case, it has to work for both types of elements :(
    >
    >My idea was to get the element under cursor, go all the way up in the DOM tree to check whether there are any elements with fixed positioning and calculate the cursor position relative to the scroll position of that element instead of documentElement's. However, I'm not sure whether this is correct or even doable.
    >
    >So the actual question is: how do I find the correct mouse position for both fixed and relatively positioned elements? Note: I don't need complete code, some hints and directions would suffice for a start.
    >
    >Thanks.
    >
    >Nikolai.


    This code is very similar to something I had to deal with last week
    where the calculations were passed on current window and not the
    document. Follows is a snippet of code I found on the web.

    This will give you the relative position of an element in the
    document, looping through all elements until it gets to the top:

    function findPos(obj)
    {
    var curleft = curtop = 0;
    if (obj.offsetParent)
    {
    do
    {
    curleft += obj.offsetLeft;
    curtop += obj.offsetTop;
    }
    while (obj = obj.offsetParent);
    return [curleft,curtop];
    }
    }

    Then , within your code:

    var posEl = findPos(document.getElementById('someElement'));
    posX = posEl[0];
    posY= posEl[1];

    From there you should be able to do your calculations (assuming I have
    understood your question).
    Tyrone Slothrop, May 17, 2011
    #2
    1. Advertising

  3. Nikolai Prokoschenko

    darwinist Guest

    On May 17, 9:51 pm, Nikolai Prokoschenko <>
    wrote:
    > Hello,
    >
    > this question is connected to AmCharts (http://amcharts.com/javascript/) but it's not *about* AmCharts, it's just the context of the problem I'm having. (NB: AmCharts' API and general code provide enough material for several pages of flaming ;))
    >
    > AmCharts, like almost every charting solution, has a concept of a "balloon", those are small popups which follow the mouse cursor and show some moreor less relevant information about the chart item under this cursor. They use some browser-detecting code to find mouse's position for these balloons, which failed for me on several occasions, so I monkey-patched that code by the code provided by Peter-Paul Koch athttp://www.quirksmode.org/js/events_properties.html. For the record, here is his code:
    >
    > function doSomething(e) {
    >         var posx = 0;
    >         var posy = 0;
    >         if (!e) var e = window.event;
    >         if (e.pageX || e.pageY)         {
    >                 posx = e.pageX;
    >                 posy = e.pageY;
    >         }
    >         else if (e.clientX || e.clientY)        {
    >                 posx = e.clientX + document.body.scrollLeft
    >                         + document.documentElement.scrollLeft;
    >                 posy = e.clientY + document.body.scrollTop
    >                         + document.documentElement.scrollTop;
    >         }
    >         // posx and posy contain the mouse position relative to the document
    >         // Do something with this information
    >
    > }
    >
    > This works splendidly in most cases, but as you can see, it's relative tothe document, which means it won't work properly for fixed elements (e.g.,lightboxed charts) when the document is scrolled. It turns out, AmCharts' original code also fails on fixed elements. By removing the scrolling position from the calculations, I'd probably get correct values for fixed elements, but instead the values would be broken for elements inside the documentflow. Unfortunately, in my case, it has to work for both types of elements:(
    >
    > My idea was to get the element under cursor, go all the way up in the DOMtree to check whether there are any elements with fixed positioning and calculate the cursor position relative to the scroll position of that elementinstead of documentElement's. However, I'm not sure whether this is correct or even doable.


    I think that will work (if I understand your question correctly). If
    it's within a fixed node, you don't substract the scrolling position.
    I've used a similar approach when deciding where there's enough space
    to position a sub-menu, which may or may not be from a fixed header,
    depending on how far the page is scrolled down. The way I check if
    something is fixed is like this:

    //////////// Start Code //////////////

    function is_fixed(element)
    {
    // While not at the top of the document tree, or not fixed, keep
    searching upwards.
    while (element.nodeName != "HTML" && used_style(element,
    "position") != "fixed")
    element = element.parentNode;
    if (element.nodeName == "HTML") return false;
    else return true;
    }

    // Used style is to get around browsers' different methods of getting
    the currently used (e.g. inline, class, etc) style for an element
    function used_style(element, property)
    {
    // getComputedStyle is the standard way but some ie versions don't
    support it
    if (window.getComputedStyle)
    style = window.getComputedStyle(element, null);
    else style = element.currentStyle;

    return style[property];
    }

    // You can get the target element of an event like this, again using
    standard or (if necssary) ie technique:
    function event_target(e) { return e.target ? e.target :
    e.srcElement; }

    //////////// End Code //////////////

    Note this is only tested in/targeted for (standards mode) ie7,8,9, and
    recent firefox, opera, safari or chrome.
    You can test the menu positioning stuff at ( http://webinterfacetricks.com
    )

    > So the actual question is: how do I find the correct mouse position for both fixed and relatively positioned elements? Note: I don't need complete code, some hints and directions would suffice for a start.
    >
    > Thanks.
    >
    > Nikolai.
    darwinist, May 18, 2011
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. MAB
    Replies:
    31
    Views:
    26,930
    chrisbster
    May 13, 2009
  2. KatB
    Replies:
    8
    Views:
    4,186
  3. Amir Kouchekinia

    Zoom relative to mouse position

    Amir Kouchekinia, May 20, 2008, in forum: Java
    Replies:
    6
    Views:
    1,749
    John B. Matthews
    May 23, 2008
  4. Alex Maghen

    Relative Positioning & Fixed Sizing in ASCX Controls

    Alex Maghen, May 6, 2006, in forum: ASP .Net Web Controls
    Replies:
    3
    Views:
    367
    Steven Cheng[MSFT]
    May 10, 2006
  5. fulio pen
    Replies:
    9
    Views:
    582
    Gus Richter
    Nov 6, 2012
Loading...

Share This Page