0

my problem is as following: On my website I want my anchor links to smoothly scroll to the ids they are linked to. There are many threads with solutions to this problem, however I am only able to use these on a jsfiddle sample project https://jsfiddle.net/7fcvkwf0/16/

$("a").each(function(index, element){
    $(this).click(function(e) {
        if (this.hash != "" && $(this).attr("href").charAt(0)=="#"){
            e.preventDefault();
            var id = $(this).attr("href");
            $('html, body').animate(
                {scrollTop: $(id).offset().top},
                1000,
                "swing",
                function(){
                console.log("done");
            });
            window.location.hash = id;
        }
    });
});

is the function I use to make the animation smooth. I don't know why, but I use the exact same code on my own homepage but it doesn't seem to work because it jumps to the anchor links immediately. The console log appears after 1000ms (1s). Unfortunately I can't show you the problem because I can't reproduce it in jsfiddle (I don't know why).

Bastian Springer
  • 271
  • 2
  • 11
  • Clear your browser's cache and retry. – Louys Patrice Bessette Apr 03 '18 at 23:01
  • My last change on the js file was the console and because it made a console entry I know that Chrome used the most current version of the script. – Bastian Springer Apr 03 '18 at 23:13
  • Try with this [**code**](https://jsfiddle.net/Bes7weB/c3on0em2/9/)... See if that is working. Notice I also changed the ` – Louys Patrice Bessette Apr 03 '18 at 23:25
  • I've tried that now, unfortunately that doesn't work either. It still seems like `e.preventDefault()` doesn't work and therefore it still jumps to the anchor immediately. The rest of the function is executed like it should. I've now also tried to add 500px to the position it is supposed to scroll to. (`$("a[name='"+name+"']").offset().top` becomes `($("a[name='"+name+"']").offset().top+500)`. It jumps to the anchor and then it doesn't scroll down the 500px. --> the animate function does not run but the callback function runs (twice because of `html, body` as the selector but that's correct). – Bastian Springer Apr 04 '18 at 10:45
  • mmm... Would it be a "slim" version of jQuery in use? – Louys Patrice Bessette Apr 04 '18 at 11:09
  • No, I use the min version of jQuery 3.2.1 (https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js) – Bastian Springer Apr 04 '18 at 11:11
  • Hey... Try to comment out `window.location.hash = "#"+name;` -- That line has no real effect in Fiddle or CodePen because it applies on a iframe... But on your page, that could be the reason. So if you want to use it, it should be in the callback of animate. – Louys Patrice Bessette Apr 04 '18 at 11:40
  • Now it doesn't animate to that anchor, it needs the 1000ms and then it jumps to anchor. – Bastian Springer Apr 04 '18 at 12:40
  • okay... So we now know what triggers the jump. But not why `.animate()` doesn't work. Try to remove the `"swing"` easing... as a test. – Louys Patrice Bessette Apr 04 '18 at 13:02
  • Removing `"swing"` doesn't do the trick :( It still jumps to the anchor after 1s. When I remove the callback function as well, it does nothing (because `window.location.hash = "#" + name;` isn't executed). – Bastian Springer Apr 04 '18 at 13:25
  • As a test I set up an interval `setInterval(function(){ $("html, body").animate( {scrolltop: 1000}, 1000, "swing", function(){ console.log("executed"); } ); }, 3000);` to test whether it scrolls to some position on the page every 3s. This did nothing, not even a jump of the scroll position. – Bastian Springer Apr 04 '18 at 13:34
  • `scrolltop` or `scrollTop` ?? Notice the capital T. ;) – Louys Patrice Bessette Apr 04 '18 at 13:59
  • yes I've noticed that but it was too late to edit the comment... doesn't work... when I put the interval into the HTML file via its own script tag it still doesn't wanna work, I've changed the selector and other things like what shall be animated. I've tried to color all text red but nothing worked out, the text stayed black, also when I put different parts of the arguments in quotation marks and so on. – Bastian Springer Apr 04 '18 at 14:20
  • Could you wrap the code with `$(document).ready(function(){` and `});`? – Louys Patrice Bessette Apr 04 '18 at 15:32
  • It is already wrapped by that – Bastian Springer Apr 05 '18 at 06:56
  • I did another test: I copied the complete code of the html, css and js files into jsfiddle and there the animation worked. I set the load type of the js to no-wrap (head). https://jsfiddle.net/Bastian2001/nx18o69b/ I don't know what the problem is... (images don't work because the paths are relative) – Bastian Springer Apr 05 '18 at 18:29
  • I also cleared the cache once more - did nothing, in Microsoft Edge it worked, in Chrome on Android (files were offline on the flash storage) - didn't work. – Bastian Springer Apr 05 '18 at 18:45

1 Answers1

0

This might help. I think it has something to do with what the event binds to. Specifically for me, I have asynchronous page loading that basically adds the anchors dynamically, therefore the prevent isn't binding to the dynamically loaded element after it's added to the dom.

$(document).on('click', 'a', function(e) {
    if (this.hash !== "") {
      e.preventDefault();
      var hash = this.hash;
      $('html, body').animate({
        scrollTop: $(hash).offset().top-150
      }, 500);
    }

});

from another thread...

Event does not bind with dynamically added element unless you delegate it to parent element or document using on(). You have to use different form of on for event delegation.

Original post This worked for me,although it kills the hash appending for reasons i cant figure out. but the scroll works consistently.

  • Sorry, I didn't tell you but I already figured it out. It had something to do with me being stupid. I forgot to tell the browser that doctype html thing.. – Bastian Springer Apr 21 '19 at 07:22