1

I am working on a one page scroll navigation. It's supposed to take the class "active" from one menu to another on scroll or when clicked, but I got this error in the console each time I click on any of the menu items:

TypeError: $(...).offset() is undefined

Below is a snippet of my code; I use jQuery 3.4.1 in my original code.

function calculateScroll() {
      var contentTop      =   [];
      var contentBottom   =   [];
      var winTop      =   $(window).scrollTop();
      var rangeTop    =   200;
      var rangeBottom =   500;
      $('.site-main-menu').find('a').each(function(){
        contentTop.push( $( $(this).attr('href') ).offset().top );
        contentBottom.push( $( $(this).attr('href') ).offset().top + $( $(this).attr('href') ).height() );
      })
      $.each( contentTop, function(i){
        if ( winTop > contentTop[i] - rangeTop && winTop < contentBottom[i] - rangeBottom ){
          $('.site-main-menu li a')
          .removeClass('active')
          .eq(i).addClass('active');        
        }
      })
    };
    
    $(document).ready(function(){
      calculateScroll();
      $(window).scroll(function(event) {
        calculateScroll();
      });
      $('.site-main-menu li').click(function() {  
        $('html, body').animate({scrollTop: $(this.hash).offset().top - 80}, 800);
        return false;
      });
    });jQuery
.menu-wrapper {position: fixed; top: 0}
.site-main-menu {list-style: none; padding: 0}
.site-main-menu li {display: inline-block;}
.site-main-menu li a {padding: 5px 10px; color: #fff; background: #000; text-decoration: none}
.site-main-menu li a.active {background-color: red}
section {padding: 50px 10px; border: 1px solid #ccc; margin-bottom: 20px; margin-top: 40px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-wrapper">
   <ul class="site-main-menu">
       <li><a class="active" href="#sec1">Menu 1</a></li>
       <li><a href="#sec2">Menu 2</a></li>
       <li><a href="#sec3">Menu 3</a></li>
    </ul>
</div>

<section id="sec1">
  <h3>Section 1</h3>
</section>

<section id="sec2">
  <h3>Section 2</h3>
</section>

<section id="sec3">
  <h3>Section 3</h3>
</section>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Sam
  • 355
  • 1
  • 16
  • @mplungjan I have tried different approach but all seemed not to work. What do you think? – Sam Aug 16 '20 at 11:53

2 Answers2

0

The TypeError is happening because this.hash is undefined here and so $(this.hash).offset() is also undefined.

$('.site-main-menu li').click(function() {  
    $('html, body').animate({scrollTop: $(this.hash).offset().top - 80}, 800);
    return false;
});
fireking-design
  • 361
  • 1
  • 9
  • But there is no difference between my code and the one you posted here. How do I fix this? – Sam Aug 15 '20 at 10:41
0

I was able to take care of the error using the pieces of JQuery below.

$(document).ready(function() {
  $('.site-main-menu li a').click(function(e) {
   e.preventDefault();
      $('html, body').animate({
          scrollTop: $($(this).attr('href')).offset().top,
        },
        1000,
        'linear'
      )
    });
  });
.menu-wrapper {position: fixed; top: 0}
.site-main-menu {list-style: none; padding: 0}
.site-main-menu li {display: inline-block;}
.site-main-menu li a {padding: 5px 10px; color: #fff; background: #000; text-decoration: none}
.site-main-menu li .active {background-color: red}
section {padding: 50px 10px; border: 1px solid #ccc; margin-bottom: 20px; margin-top: 40px}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="menu-wrapper">
   <ul class="site-main-menu">
       <li><a class="active" href="#sec1">Menu 1</a></li>
       <li><a href="#sec2">Menu 2</a></li>
       <li><a href="#sec3">Menu 3</a></li>
    </ul>
</div>

<section id="sec1">
  <h3>Section 1</h3>
</section>

<section id="sec2">
  <h3>Section 2</h3>
</section>

<section id="sec3">
  <h3>Section 3</h3>
</section>
Sam
  • 355
  • 1
  • 16