phmsk
phmsk

Reputation: 186

Get element offset relative to grand-...-grand--parent

I would like to get the position of #mainChildElement relative to .grand-grand-grand-parent using javascript/jquery. I tried doing $('#mainChildElement').offset().top however this just returns the offset relative to the immediate parent.

Would I have to recursively find the position by iterating through the tree and sum the top offset of each element until I hit the .grand-grand-grand-parent or is there a more elegant solution?

<div class="grand-grand-grand-parent">
    <div class="grand-grand-parent">
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
    </div>
    <div class="grand-grand-parent">
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
        <div class="grand-parent">
            <div class="parent">
                <div id="mainChildElement" class="child-element">
                    Where am I?!
                </div>
            </div>
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 0

Views: 1063

Answers (2)

Takit Isy
Takit Isy

Reputation: 10081

An easy solution is to calculate the .offset()s difference of the element with the reference you want to use.

Doc about .offset(): https://api.jquery.com/offset/

Description: Get the current coordinates of the first element in the set of matched elements, relative to the document.

var ref_top = $('#gggp').offset().top;
var child_top = $('#mainChildElement').offset().top;
var diff = child_top - ref_top;

console.log('Reference:', ref_top + 'px');
console.log('Child:', child_top + 'px');
console.log('Difference:', diff + 'px');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="gggp" class="grand-grand-grand-parent">
  <div class="grand-grand-parent">
    <div class="grand-parent">
      <div class="parent">
        <div class="child-element">
          Content goes here!
        </div>
      </div>
    </div>
    <div class="grand-parent">
      <div class="parent">
        <div class="child-element">
          Content goes here!
        </div>
      </div>
      <div class="parent">
        <div class="child-element">
          Content goes here!
        </div>
      </div>
    </div>
  </div>
  <div class="grand-grand-parent">
    <div class="grand-parent">
      <div class="parent">
        <div class="child-element">
          Content goes here!
        </div>
      </div>
    </div>
    <div class="grand-parent">
      <div class="parent">
        <div id="mainChildElement" class="child-element">
          Where am I?!
        </div>
      </div>
      <div class="parent">
        <div class="child-element">
          Content goes here!
        </div>
      </div>
    </div>
  </div>
</div>

Hope it helps.

Upvotes: 1

dgeare
dgeare

Reputation: 2658

You can get their position relative to the screen with getClientBoundingRect() and measure the difference. https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

const parent = document.querySelector('.grand-grand-grand-parent');
const child = document.querySelector('#mainChildElement');
console.log(child.getBoundingClientRect().top - parent.getBoundingClientRect().top); 
<div class="grand-grand-grand-parent">
    <div class="grand-grand-parent">
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
    </div>
    <div class="grand-grand-parent">
        <div class="grand-parent">
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
        <div class="grand-parent">
            <div class="parent">
                <div id="mainChildElement" class="child-element">
                    Where am I?!
                </div>
            </div>
            <div class="parent">
                <div class="child-element">
                    Content goes here!
                </div>
            </div>
        </div>
    </div>
</div>

Upvotes: 0

Related Questions