No easy way to get position of SVGElement relative to an ancestor element (svg or html)

RESOLVED WORKSFORME

Status

()

Core
SVG
--
enhancement
RESOLVED WORKSFORME
12 years ago
9 years ago

People

(Reporter: Jesse Costello-Good, Unassigned)

Tracking

Trunk
Points:
---

Firefox Tracking Flags

(Not tracked)

Details

(Reporter)

Description

12 years ago
User-Agent:       Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Build Identifier: Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0

Because the SVGElement class does not define the properties offsetWidth, offsetHeight, scrollLeft, scrollTop, offsetTop, and offsetLeft there is no way to programmatically obtain the position of an svg element relative to other elements in the same page.

Theoretically you could write a function that used the width, height, style, and transform properties to obtain the position of an svg element. Such a function would be very complicated and would duplicate much of the logic that already exists in the SVG code.

Reproducible: Always



Expected Results:  
Ideally, SVGElement would be compatible with the following function, which works for any two HTMLElements and which returns the object {L:l,T:t,W:w,H:h} where
* w is the pixel width of objGUI
* h is the pixel height of objGUI
* l is the left pixel offset between objRoot and objGUI
* t is the top pixel offset between objRoot and objGUI

  function getRelativePosition(objRoot, objGUI) {
    //initialize
    var objDimension = {W:objGUI.offsetWidth, H:objGUI.offsetHeight};
    var intLeft = objGUI.scrollLeft;
    var intTop = objGUI.scrollTop;
    var intLeftBorder = 0;
    var intTopBorder = 0;
    var ot = objGUI.offsetTop;
    var ol = objGUI.offsetLeft;
    var sl = objGUI;
    var sht = 0;
    var shl = 0;
    var bW;

    //account for initial scroll offset (while statement below starts with parent, not self) as well as border
    if(objGUI.offsetParent) {
      shl -= objGUI.offsetParent.scrollLeft;
      sht -= objGUI.offsetParent.scrollTop;

      bW = objGUI.offsetParent.style.borderLeftWidth ? parseInt(objGUI.offsetParent.style.borderLeftWidth) : 0;
      if(!isNaN(bW)) intLeftBorder += bW;
      bW = objGUI.offsetParent.style.borderTopWidth ? parseInt(objGUI.offsetParent.style.borderTopWidth) : 0;
      if(!isNaN(bW)) intTopBorder += bW;
    }

    while((objGUI = objGUI.offsetParent) != null && objGUI != objRoot) {
      ot += objGUI.offsetTop;
      ol += objGUI.offsetLeft;

      if(objGUI.offsetParent) {
        //calculate the borders if the parent exists
        bW = objGUI.offsetParent.style.borderLeftWidth ? parseInt(objGUI.offsetParent.style.borderLeftWidth) : 0;
        if(!isNaN(bW)) intLeftBorder += bW;
        bW = objGUI.offsetParent.style.borderTopWidth ? parseInt(objGUI.offsetParent.style.borderTopWidth) : 0;
        if(!isNaN(bW)) intTopBorder += bW;
        //account for scrolling parent
        shl += objGUI.offsetParent.scrollLeft;
        sht += objGUI.offsetParent.scrollTop;
      }

      if(objGUI.offsetParent && objGUI.offsetParent.offsetParent) {
        //account for the scrollposition for the parent
        var scrollTop = objGUI.offsetParent.scrollTop;
        if(!isNaN(scrollTop)) sht -= scrollTop;
        var scrollLeft = objGUI.offsetParent.scrollLeft;
        if(!isNaN(scrollLeft)) shl -= scrollLeft;
      }
    }
    objGUI = sl;

    while((objGUI = objGUI.parentNode) != null && objGUI != objRoot) {
      if(objGUI.parentNode && objGUI.parentNode.parentNode && !(objGUI.parentNode.tagName && objGUI.parentNode.tagName.toUpperCase() == "BODY")){
        var scrollTop = objGUI.parentNode.scrollTop;
        if(!isNaN(scrollTop) && scrollTop > 0 ) sht -= scrollTop;
        var scrollLeft = objGUI.parentNode.scrollLeft;
        if(!isNaN(scrollLeft) && scrollLeft > 0 ) shl -= scrollLeft;
      }
    }

    //Formula: intLeft + 2(intLeftBorder) (what the hell???)
    objDimension.L = ol + shl + (2*intLeftBorder);
    objDimension.T = ot + sht + (2*intTopBorder);
    return objDimension;
  };
(Reporter)

Updated

12 years ago
Severity: normal → enhancement
(Reporter)

Updated

12 years ago
Blocks: 339186
Assignee: nobody → general
Component: General → SVG
Product: Firefox → Core
QA Contact: general → ian
Version: unspecified → 1.8 Branch
Note you can now use the new getClientRects or getBoundingClientRect methods with SVG:

http://developer.mozilla.org/en/docs/DOM:element.getClientRects
http://developer.mozilla.org/en/docs/DOM:element.getBoundingClientRect

Does this meet your needs?
Version: 1.8 Branch → Trunk
Assignee: general → nobody
QA Contact: ian → general
Assuming it does since there's been no reply in two years.
Status: UNCONFIRMED → RESOLVED
Last Resolved: 9 years ago
Resolution: --- → WORKSFORME
You need to log in before you can comment on or make changes to this bug.