4

I know that we can get width and height using clientWidth and clientHeight, however how do I figure out the top left x and top left y position of an element?

xonegirlz
  • 8,889
  • 19
  • 69
  • 127

7 Answers7

7
function findPosX(obj)
  {
    var curleft = 0;
    if(obj.offsetParent)
        while(1) 
        {
          curleft += obj.offsetLeft;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.x)
        curleft += obj.x;
    return curleft;
  }

  function findPosY(obj)
  {
    var curtop = 0;
    if(obj.offsetParent)
        while(1)
        {
          curtop += obj.offsetTop;
          if(!obj.offsetParent)
            break;
          obj = obj.offsetParent;
        }
    else if(obj.y)
        curtop += obj.y;
    return curtop;
  }

Retrieve the position (X,Y) of an HTML element

Find X/Y of an HTML element with JavaScript

These two links should be helpful.

Community
  • 1
  • 1
Sameera Thilakasiri
  • 9,452
  • 10
  • 51
  • 86
4

To get the top you need to add the offsetTop of the element and the element's offsetParent's offsetTop. Do this all the way up the DOM to the document. That accounts for absolute, relative and fixed positioning. To get the left, do the same thing with offsetLeft.

These two functions add two properties to Element, documentOffsetTop and documentOffsetLeft, that will get top/left of any element:

window.Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

window.Object.defineProperty( Element.prototype, 'documentOffsetLeft', {
    get: function () { 
        return this.offsetLeft + ( this.offsetParent ? this.offsetParent.documentOffsetLeft : 0 );
    }
} );

This demo shows several combinations of element layout, comparing documentOffsetTop with jQuery's offset().top.

Demo: http://jsfiddle.net/ThinkingStiff/3G7EZ/

Script:

window.Object.defineProperty( Element.prototype, 'documentOffsetTop', {
    get: function () { 
        return this.offsetTop + ( this.offsetParent ? this.offsetParent.documentOffsetTop : 0 );
    }
} );

var line = document.getElementsByClassName( 'grid-line' )[0],
    grid = document.getElementById( 'grid' );

for( var index = 2; index < 100; index++ ) {
    var copy = line.cloneNode();
    copy.textContent = ( index * 10 );
    grid.appendChild( copy );
};

var offset = document.getElementById( 'absolute' );
offset.textContent = 'absolute: ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'static' );
offset.textContent = 'static: ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'static2' );
offset.textContent = 'static: ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'relative' );
offset.textContent = 'relative: ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'fixed-side' );
offset.textContent = 'fixed/absolute (side): ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'fixed-top' );
offset.textContent = 'fixed/absolute (top): ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.getElementById( 'fixed-bottom' );
offset.textContent = 'fixed/absolute (bottom): ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.querySelectorAll( '#relative-wrapped-absolute div' )[0];
offset.textContent = 'absolute/relative/static (absolute/relative wrapped): ' 
    + offset.documentOffsetTop + ', $' 
    + $( offset ).offset().top;

offset = document.querySelectorAll( '#static-wrapped-static div' )[0];
offset.textContent = 'static (static wrapped): ' 
    + offset.documentOffsetTop  + ', $' 
    + $( offset ).offset().top;

HTML:

<div id="static" class="offset">0</div>
<div id="static2" class="offset">0</div>
<div id="static-wrapped-static"><br /><div class="offset">0</div></div>
<div id="absolute" class="offset">0</div>
<div id="relative" class="offset">0</div>
<div id="fixed-side" class="offset">0</div>
<div id="fixed-top" class="offset">0</div>
<div id="fixed-bottom" class="offset">0</div>
<div style="position: relative;"><div id="relative-wrapped-absolute"><div class="offset">0</div></div></div>

<div id="grid"><div class="grid-line">10</div></div>

CSS:

body {padding-left: 12px;}

#absolute {
    top: 100px;
    position: absolute;
}

#relative {
    top: 150px;
    position: relative;
}

#fixed-side {
    right: 0;
    position: fixed;
}

#fixed-top {
    left: 50%;
    position: fixed;
    top: 0;
}

#fixed-bottom {
    left: 50%;
    position: fixed;
    bottom: 0;
}

#relative-wrapped-absolute {
    top: 8px;
    position: relative;
}

#relative-wrapped-absolute div {
    position: absolute;
    top: 20px;
}

.offset {
    border: 1px solid black;
}

#grid {
    height: 100%;
    left: 0;
    position: absolute;
    top: 1px;
    width: 100%;
    z-index: -1;
}

.grid-line {
    border-bottom: 1px solid lightgray;
    font-size: 8px;
    height: 9px;
    line-height: 20px;
}

Output:

enter image description here

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
4

Using jQuery you can do this by calling .position() function. Like:

$('#mydiv').position().left;
$('#mydiv').position().top;

This is the most reliable way, since it already calculates the position checking the CSS of elements and its parents.

You can see the full implementation here:

http://code.jquery.com/jquery-1.7.1.js at line 9077

WoLfulus
  • 1,948
  • 1
  • 14
  • 21
3

Do you need the x and y for a specific element.

$("#bnElement").offset().left;
$("#bnElement").offset().top;

Just have a look at the following post jQuery x y document coordinates of DOM object regards

Community
  • 1
  • 1
Captain0
  • 2,583
  • 2
  • 28
  • 44
0

Using querySelectorAll() method

    var domTree = [];
var allelems = document.querySelectorAll(tagsCheck ); // for all tags use --> '*'

for(var i = 0; i < allTags.length; i++){
    console.log(i+'  '+'Tag : '+ allTags[i].nodeName+'#'+allTags[i].id);  // getPath(allTags[i]);

    getPosition(allTags[i]);
    console.log('Coordinates  : {top   : '+allTags[i].getBoundingClientRect().top+', left   : '+allTags[i].getBoundingClientRect().left+' } ');

    console.log('Dimensions offset       :  {width : '+allTags[i].offsetWidth+', height : '+allTags[i].offsetHeight+' } ');
    console.log('Dimensions style  Q     :  {width : '+allTags[i].style.width+', height : '+allTags[i].style.height+' } '); 

    var singleTag = [];
    var jsonData = getTagInfo(allelems[i]); //singleTag.push(getFullXPath(allelems[i]));
    singleTag.push(jsonData);
    domTree.push(singleTag);
console.log(singleTag);

}
function getTagInfo(element){ 
    return '{ \"Xpath\": \"'+ getFullXPath(element) + '\", \"left\": '+element.getBoundingClientRect().left+',\"top\":  '+element.getBoundingClientRect().top+
    ',\"width\": '+element.offsetWidth+',\"height\" : '+element.offsetHeight+'}';
}

Using getElementsByTagName() and getComputedStyle()

function getElementDimensions(tagsCheck){
    var allElem = document.getElementsByTagName('*'); 
    for(i = 0, j = 0; i < allElem.length; i++) { 
        var elemstyle= window.getComputedStyle(allElem[i], null);
        if( tagsCheck.indexOf( allElem[i].tagName ) > -1 ){
            console.log(i+'  '+'Tag : '+allElem[i].tagName+'[@id : '+allElem[i].id);
            console.log('Dimensions style  E     :  {width : '+elemstyle.width+', height : '+elemstyle.height+' } '); 
        }
    }
}

position and XPath of an HTML element

function getPosition(element){ 
    var xPosition = 0; 
    var yPosition = 0; 
        while(element) { 
            xPosition += (element.offsetLeft - element.scrollLeft + element.clientLeft);
            yPosition += (element.offsetTop - element.scrollTop + element.clientTop); 
        element = element.offsetParent; 
        }
    console.log('GetPosition  : {top   : '+yPosition+', left   : '+xPosition+' } ');
}
Community
  • 1
  • 1
Yash
  • 9,250
  • 2
  • 69
  • 74
0

I really liked jquery.simulate implementation

function findCorner(elem) {
    var offset,
        document = $(elem.ownerDocument);
    elem = $(elem);
    offset = elem.offset();

    return {
        x: offset.left - document.scrollLeft(),
        y: offset.top - document.scrollTop()
    };
}

seems to capture a lot of scenarios. it brings you the position relative to screen.. so if I scrolled, some items may be in negative position. which is useful for automated tests that use drag & drop.

You can easily wrap it with jquery for cool syntax like so

$.fn.findCorner = function(){
    if ( this.length > 1 ) {
        return this.map(function(){ return findCorner(this); })
    } else {
        return findCorner(this[0]);
    }
};

and so do $('div').findCorner()..

guy mograbi
  • 27,391
  • 16
  • 83
  • 122
0

Maybe this can help you. ?!

HTML

    <div>
    <p>Hello</p>
    </div>
    <p></p>

CSS

div { padding: 50px;}
p { margin-left:10px; }

JS

    var p = $("p:first");
    var position = p.position();
    $("p:last").text( "left: " + position.left + ", top: " + position.top );

Demo: http://jsfiddle.net/bZezzz/TvMMv/

bZezzz
  • 972
  • 9
  • 22