Nicholas Bates Nicholas Bates - 3 months ago 9
Javascript Question

How can I get the position of an element relative to the broswer viewport

I have a div (

#dynamic
) and I would like to get the values of its position relative to the browser viewport as the user scrolls down the page.

Currently my code snippet returns the incorrect result as I attempt to set the bottom position of the
headingDiv
div to the top of the
#dynamic
div. Fixing this would solve my problem. To be clear, the orange box should shrink as the text comes up.

I have seen this question where user 'codef0rmer' suggested to use
$("#dynamic").offset().top;
however for me, this just yielded the same result.

Here is the code in case the jsfiddle breaks:



function sizeHeader() {
var navPos = document.getElementById("nav");
var dynPos = document.getElementById("dynamic");
$("#headingDiv").css("top", navPos.getBoundingClientRect().bottom);
$("#headingDiv").css("bottom", dynPos.getBoundingClientRect().top);
}
$(window).scroll(function() {
sizeHeader();
});
window.onload = sizeHeader();

/* Normalisation */
* {
margin: 0 0 0 0;
padding: 0 0 0 0;
}

/* Navigation bar */
nav {
display: block;
background-color: black;
color: #FFFBD0;
padding: 1%;
position: fixed;
right: 0;
left: 0;
bottom: auto;
z-index: 100;
}

/* Main content */

#headingDiv {
position: fixed;
left: 0;
right: 0;
top: 3em;
bottom: auto;
background-color: peru;
display: flex;
justify-content: center; /* align horizontal */
align-items: center; /* align vertical */
}

#dynamic {
padding: 1%;
position: relative;
top: 55vh;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>

<body>
<nav id="nav">
<b>Hello</b>
</nav>
<div id="headingDiv"><h1>greetings</h1></div>
<main id="dynamic">
<p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p>
<p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p> <p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p><p>ello</p>
</main>
<script src="main.js"></script>
</body>




Answer

You were getting the top position of the dynamic div, which is measured from the top of the window... but then using that to set the bottom of the header. The "bottom" css property is measured from the bottom of the window or page.

When #dynamic is near the top of the window, it gets smaller (say 20px). But you want the bottom of the header to get further away from the bottom of the window (20px from the bottom). So you need to subtract one from the other.

window.innerHeight - dynamic.getBoundingClientRect().top;

jsFiddle