Polar
Polar

Reputation: 3537

How to achieve the same function of position:sticky using jQuery or JavaScript?

I'm having a hard time figuring out why the code below doesn't work as expected.

What I'm trying to achieve is same functionality with position:sticky whereas when the scrolled reaches the top of the #second-header then fixes its position below the #header which is also fixed, however, the height of the #header is unknown which is I believe can be calculated using the function outerHeight(true) on JQuery.

Then after reaching out to the bottom of the #second-header-container, remove the fixed position of #second-header turning it back to normal position.

Due to browser compatibility issues and other customization, I cannot simply use the position:sticky of css.

It looks like my logic is wrong, and I need help.

jQuery(document).ready(function(){
	var $document = jQuery(document);
	var header = jQuery('#header');
    var second_header = jQuery('#second-header-container').find('#second-header');
	var second_header_container = jQuery('#second-header-container');
  
    var second_header_offset = second_header.offset().top;
	var second_header_container_offset = second_header_container.offset().top;
	
  jQuery(window).scroll(function(){
	  var top_margin = header.outerHeight(true);
	  var second_header_height = second_header.outerHeight(true);
	  var second_header_container_height = second_header_container.outerHeight(true);
    
      if( jQuery(window).scrollTop() > (second_header_offset - second_header_height) && jQuery(window).scrollTop() < second_header_container_height) {  
			second_header.addClass('fixer');
			second_header.css({position:'fixed', top:top_margin, 'z-index':'999999'});
	  } else {
			second_header.removeClass('fixer');
			second_header.css({position:'relative', top:'0px', 'z-index':'0'});    
      }
  });
});
*{
  color: #FFFFFF;
  padding: 0;
  margin: 0;
}

.fixer{
  position: fixed;
  width: 100%;
}

#header, .banner, #second-header, .contents{
  padding: 5px;
}
#header{
  position: fixed;
  width: 100%;
  height: 74px;
  z-index: 99999;
  background-color: #000000; 
}
.banner{
  padding-top: 84px;
  height: 200px;
  background-color: #583E5B;
}
#second-header-container{
  min-height: 300px;
  background-color: #775F5E;
}
#second-header{
  padding-bottom: 10px;
  padding-top: 10px;
  background-color: #4C3D3C;
}
.contents{
  min-height: 200px;
  background-color: #97A36D;
}
.footer{
  background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
  <div id="second-header">SECOND-HEADER</div>
  <!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>

Upvotes: 0

Views: 1713

Answers (1)

SpiritOfDragon
SpiritOfDragon

Reputation: 1432

To achieve this you need first check if the scroll height is near the second div header and within the height of the second div. Then add a class that make it stick below the main header. I have created a sticky class and added it while scrolling conditions are met.

Please check below code

jQuery(document).ready(function() {
  var headerHeight = $('#header').outerHeight(true);
  var secondHeaderContainer = $('#second-header-container');
  const secondHeaderTopPos = secondHeaderContainer.offset().top;
  const secondHeaderContainerHeight = $(secondHeaderContainer).height();

  $(window).scroll(function() {
    const scrollTop = $(this).scrollTop();
    const secondContainerHeightEnd = secondHeaderContainerHeight + secondHeaderTopPos - $('#second-header').height() - headerHeight;

    if (((secondHeaderTopPos - headerHeight) <= scrollTop) && (secondContainerHeightEnd >= scrollTop)) {
      $('#second-header').addClass('sticky').css('top', headerHeight);
    } else {
      $('#second-header').removeClass('sticky');
    }
  });
});
* {
  color: #FFFFFF;
  padding: 0;
  margin: 0;
}

.sticky {
  position: fixed;
  width: 100%;
  top: 0;
  left: 0;
}

.fixer {
  position: fixed;
  width: 100%;
}

#header,
.banner,
#second-header,
.contents {
  padding: 5px;
}

#header {
  position: fixed;
  width: 100%;
  height: 74px;
  z-index: 99999;
  background-color: #000000;
}

.banner {
  padding-top: 84px;
  height: 200px;
  background-color: #583E5B;
}

#second-header-container {
  min-height: 300px;
  background-color: #775F5E;
}

#second-header {
  padding-bottom: 10px;
  padding-top: 10px;
  background-color: #4C3D3C;
}

.contents {
  min-height: 200px;
  background-color: #97A36D;
}

.footer {
  background-color: #80A379;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header id="header">HEADER</header>
<div class="banner">BANNER</div>
<div id="second-header-container">
  <div id="second-header">SECOND-HEADER</div>
  <!--Other contents and elements...-->
</div>
<div class="contents">OTHER...</div>
<footer class="contents footer">FOOTER</footer>

Upvotes: 1

Related Questions