3

I am using this script to scroll to an anchor:

$( document ).ready(function(e) 
{
    var $root = $('html, body');
    $('a').click(function(e) {
        e.preventDefault();
        var href = $.attr(this, 'href');

        if(href!=='javascript:void(0)' && href!=='javascript:void(0);'){
            $root.animate({
                scrollTop: $(href).offset().top-100
            }, 1000, function (e) {
                e.preventDefault();
                window.location.hash = href;
            });
            return false;
        }
    });

});

However, after I clicked a link (and the animation finishes), I get the following error twice: Uncaught TypeError: Cannot read property 'preventDefault' of undefined

I don't understand why. I tried to add the e to the function but it still gives the error. Could someone give some background information?

Jordy
  • 4,719
  • 11
  • 47
  • 81
  • 2
    You have added `e.preventDefault();` to the `.animate` callback function. What are you expecting this to do? – Turnip Jan 04 '19 at 12:58

1 Answers1

5

The problem is...

$( document ).ready(function(e) 
{
    var $root = $('html, body');
    $('a').click(function(e) {
        e.preventDefault();
        var href = $.attr(this, 'href');

        if(href!=='javascript:void(0)' && href!=='javascript:void(0);'){
            $root.animate({
                scrollTop: $(href).offset().top-100
            }, 1000, function (e) {
//                             ^−−−−−−−−−−−−−−−−−−−−−− here
                e.preventDefault();             // <−− and/or (arguably) here
                window.location.hash = href;
            });
            return false;
        }
    });

});

The animate callback doesn't receive an event object.

It's not clear what you're trying to prevent at that point, as you've already prevented the default of the event that occurred (the click). Simply remove the e indicated above and also the e.preventDefault() call within the animate callback.


In a comment you've added:

The problem is, because the scroll-to-element has an offset of -100, the page jumps a bit after it updates the URL. I want to prevent that, so that's why I have this e.preventDefault(); within the animate callback. If I remove it, it still makes this weird jump.

The only reason it doesn't have that jump with the call there is that the call throws an error, so the next line never runs, so it never sets the URL.

If you want to set the URL without changing the page or scroll position, use history.replaceState instead:

history.replaceState(null, "", href);
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • The problem is, because the scroll-to-element has an offset of `-100`, the page jumps a bit after it updates the URL. I want to prevent that, so that's why I have this `e.preventDefault();` within the `animate` callback. If I remove it, it still makes this weird jump. – Jordy Jan 04 '19 at 13:13
  • 1
    @Jordy then perhaps this will be useful: https://stackoverflow.com/questions/1489624/modifying-document-location-hash-without-page-scrolling – Turnip Jan 04 '19 at 13:18
  • 1
    @Jordy - I've added to the bottom of the answer to respond to that comment. – T.J. Crowder Jan 04 '19 at 13:23