Cole McKim
Cole McKim

Reputation: 11

Getting height of div when it does not have a specified class

building, and I ran into an issue in my javascript (plain javascript). I have an fixed nav bar that shrinks when the user scrolls down. I don't use sticky elements because they run into difficulties with certain computers. When the user scrolls down, this class is added to the nav bar.

.sticky {
    position: fixed;
    padding: 10px 5% 10px 5%;
    background-image: linear-gradient(rgb(0, 0, 0),rgb(0, 0, 0));
}

Since this nav bar is never relative, I add a margin to the top of the second element in the body. Like this:

var mainNav = document.querySelector(".header-nav");
var tmp = document.getElementsByTagName('HEADER')[0];

tmp.nextElementSibling.style.marginTop = mainNav.offsetHeight + "px";

window.addEventListener("resize", function(event) {
    tmp.nextElementSibling.style.marginTop = mainNav.offsetHeight + "px";
})

The issue I am running into deals with my resize function that I use because the header needs to change in height depending on browser size. Now if I resize the page at the top of the page, when the header is unshrunk (say 150px), everything works fine. But if I scroll to the middle of the page when the navbar is smaller, say 70 pixels tall, then when I scroll back up, the marginTop of the second element is only 70px versus the 150px I need it to be when the navbar grows again. Hope this makes my problem clear. I am wondering if there is a way to get mainNav.offsetHeight as a value like mainNav(without .sticky class).offsetHeight

Upvotes: 1

Views: 63

Answers (1)

terrymorse
terrymorse

Reputation: 7096

From the question:

I am wondering if there is a way to get mainNav.offsetHeight as a value like mainNav(without .sticky class).offsetHeight

The problem is how to determine both the default (no .sticky) and .sticky heights of the header.

Here's a trick to do that:

A. Clone the header and make the clone invisible,

B. Add cloned header after the real header,

C. Determine the default and .sticky heights of the cloned header,

D. Remove the cloned header from the DOM,

E. Return default and .sticky offset heights.

function getHeaderHeights() {
  const hdr = document.querySelector('.header-nav');
  const hdrClone = hdr.cloneNode(true);
  hdrClone.style.opacity = 0;
  hdr.insertAdjacentElement('afterend', hdrClone);

  const defaultHeight = hdrClone.offsetHeight;

  hdrClone.classList.add('sticky');
  const stickyHeight = hdrClone.offsetHeight;
  hdrClone.remove();
  return {
    defaultHeight,
    stickyHeight
  };
}

const {
  defaultHeight,
  stickyHeight
} = getHeaderHeights();
console.log(`Header ht: ${defaultHeight}, stickyHt: ${stickyHeight}`);
.header-nav {
  background-color: #a0a0a0;
  padding: 40px 5%;
  color: white;
  width: 100%;
}

.sticky {
  position: fixed;
  padding: 10px 5% 10px 5%;
  background-image: linear-gradient(rgb(0, 0, 0), rgb(0, 0, 0));
}
<header class="header-nav">
  This is a sample header.<br> It has two lines of text.
</header>

Upvotes: 1

Related Questions