Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript

Joshua Thorley
Joshua Thorley
7,886 Points

Why does my code work until I try to store it in a function?

I have put together a one page site using bootstrap, and have used the navbar links to scroll to anchor elements further down the page.

The problem I had is that the navbar is sticky, and when it scrolls down to the relevant section of the page, the navbar itself covers a small amount of the relevant content.

I did a bit of rummaging on google and managed to clobber together this code to stop it from scrolling quite so far down each time:

$('.navbar a').not('first').on( 'click', function(){
     var offset = 80;
  $('body').animate( {
     scrollTop: $($(this).attr('href') ).offset().top - offset + 'px'
     }, 800);
  });

This worked absolutely perfectly. I then found that I needed to reuse the code for a button that linked down to an anchor, so obviously I tried to add the code to a function and call it each time:

function scrollAdjust() {
  var offset = 80;
  $('body').animate( {
    scrollTop: $($(this).attr('href') ).offset().top - offset + 'px'
  }, 800);
  }

$('.navbar a').not('first').on( 'click', scrollAdjust());

Admittedly, my brain is a little fried from the front-end dev track so I might be missing something glaringly obvious but I really can't figure out where I'm going wrong?

Ben Schroeder
Ben Schroeder
22,817 Points

Are you getting any errors in your browser's JavaScript console when you try to click the element?

Joshua Thorley
Joshua Thorley
7,886 Points

I get one once the page is loaded, but can't figure out how to solve it:

Uncaught TypeError: Cannot read property 'top' of undefinedscrollAdjust @ titlescroll.js:4(anonymous function) @ titlescroll.js:8

2 Answers

Steven Parker
Steven Parker
215,954 Points

:point_right: You want to name the function to establish the handler, not invoke it:

$('.navbar a').not('first').on('click', scrollAdjust);
Joshua Thorley
Joshua Thorley
7,886 Points

Hi Steven, thanks for helping!

Unfortunately, your solution doesn't seem to solve the problem. I'm still getting the following error in the JS console once the page is loaded:

Uncaught TypeError: Cannot read property 'top' of undefinedscrollAdjust @ titlescroll.js:4(anonymous function) @ titlescroll.js:8

Steven Parker
Steven Parker
215,954 Points

Joshua Thorley, I accidentally sent you down the wrong path :flushed:   I revised my answer, see above. :arrow_heading_up:

Joshua Thorley
Joshua Thorley
7,886 Points

Thanks Steven! It worked.

Can I ask: maybe it's down to the fact I have only completed a few JS courses, but this seems to go against what I have learnt so far. Is there a specific reason in this instance that I don't call the function? I thought you had to call a function in order to execute it?

Steven Parker
Steven Parker
215,954 Points

Yes, but at this point you don't want to call it. You just want to set things up so the event will call it.

In the ".on()" call you are giving the event the function to use. If you invoke it now, you would be giving the event the result of this function to use, which in this case is undefined since the function has no return value.

Joshua Thorley
Joshua Thorley
7,886 Points

That makes sense, thanks!

Steven Parker
Steven Parker
215,954 Points

Happy to help. Remember to choose a "best answer" to mark the question closed.

Karolin Rafalski
Karolin Rafalski
11,368 Points

It could be a scoping issue. Is your value of top global or inside another function?

If the value of top is in another function, it is not available to your new function.