2

i tried to add a smoothScroll animation on each button that has a .smoothScroll class.

so i did this:

// SmoothSCroll
var smoothScroll = document.querySelectorAll('.smoothScroll');
[].forEach.call(smoothScroll, function (el) {
  el.addEventListener('click', function() {
        var offset = $(this.hash).offset().top;
        $('html, body').stop().animate({
            scrollTop: offset - (window.innerHeight/2) + ($(this.hash).innerHeight()/2)   
        }, 400 ); 
        return false;
  });
});

https://jsfiddle.net/jt2jo3pt/2/

I don't know if you noticed what happened, but there is a little flash when the click triggered ( the scrollbar goes down a little before smoothscrolling )

But when i tried with full Jquery like this:

$('.smoothScroll').click(function(e){
        var offset = $(this.hash).offset().top;
        $('html, body').stop().animate({
            scrollTop: offset - (window.innerHeight/2) + ($(this.hash).innerHeight()/2)   
        }, 400 ); 
    return false;
});

I don't have this bubbling effect: https://jsfiddle.net/34w72v1v/

Do you have any idea what could cause this issue with querySelectorAll method?

I try to not use jQuery so i need to know what's happening to learn :)

Thanks for your time.

Gbreux
  • 361
  • 1
  • 4
  • 14
  • 1
    `$('html, body').stop().animate({ scrollTop: offset - (window.innerHeight/2) + ($(this.hash).innerHeight()/2) }, 400 );` does not look like _I try to not use jQuery_. – Regent Apr 30 '15 at 13:34
  • Why would you try *not* to use jQuery? It's there to make things simpler and shorter. If it is already in the website, then not using it is a waste :) – iCollect.it Ltd Apr 30 '15 at 13:34
  • It is just for learning purpose. – Gbreux Apr 30 '15 at 13:34
  • I don't see the effect you describe (Firefox). Both fiddles do the same thing (except for the style difference). – Pointy Apr 30 '15 at 13:35
  • 1
    FWIW, `return false` has no special side-effect in `addEventListener` handlers. – Lye Fish Apr 30 '15 at 13:36
  • It is a pretty fast effect, look at the scrollbar maybe you will see it, or is it only with mac (chrome and firefox tested) ? – Gbreux Apr 30 '15 at 13:37
  • 1
    I see what you're talking about in Chrome. Check out the answers below, they're spot on. – Fata1Err0r Apr 30 '15 at 13:39

2 Answers2

5

You need to preventDefault() in javascript to stop the window moving to the bookmark anchor:

// SmoothSCroll
var smoothScroll = document.querySelectorAll('.smoothScroll');
[].forEach.call(smoothScroll, function (el) {
  el.addEventListener('click', function(el) {
      el.preventDefault();
        var offset = $(this.hash).offset().top;
        $('html, body').stop().animate({
            scrollTop: offset - (window.innerHeight/2) + ($(this.hash).innerHeight()/2)   
        }, 400 ); 
  });
});

return false is just a shortcut used for jQuery events to trigger both e.preventDefault() and e.stopPropagation().

https://jsfiddle.net/TrueBlueAussie/jt2jo3pt/4/

iCollect.it Ltd
  • 92,391
  • 25
  • 181
  • 202
  • Thank you for your fast answer, i didn't know for the return false and i did try with preventDefault but i didn't prevent on the right call (i did on .call instead of the listerner.. awfull :D) Thanks again! (you were too fast, i can't accept the answer right know, i will asap :)) – Gbreux Apr 30 '15 at 13:43
3

It's because of the return false. In jQuery, returning false from an event handler prevents the default behaviour taking place. In a (non-inline) JavaScript event handler, it does nothing. For more info, see this excellent answer.

Since your trigger is a <a href="#test" class="smoothScroll">Go to test</a>, upon clicking it the non-jQuery version is taking you down to the #test element, but in jQuery it isn't (since the default behaviour is being cancelled)... hence the flash.

If you either don't return false in jQuery, or add e.preventDefault() in the JavaScript version, you'll notice you can control the flash.

https://jsfiddle.net/34w72v1v/1/
https://jsfiddle.net/jt2jo3pt/3/

Community
  • 1
  • 1
Matt
  • 74,352
  • 26
  • 153
  • 180
  • 1
    Nitpick... Only in `addEventListener()` handlers does `return false;` do nothing. In "property bound" handlers, it triggers `e.preventDefault();`. :-) – Lye Fish Apr 30 '15 at 13:42
  • Thanks for your answer, it's pretty clear to me now :) – Gbreux Apr 30 '15 at 13:54