1

I've set up a single page website with smooth scrolling that strips the anchor link from the URL after smooth scrolling. Here's the jQuery I'm using :

$(function() {
    $('a.page-scroll').on('click', function(event) {
        var $anchor = $(this);
        $('html, body').stop().animate({
            scrollTop: $($anchor.attr('href')).offset().top  - 60
        }, 1000, 'easeInOutExpo');
        event.preventDefault();
    });
});

Everything works great until I added other pages. I can't get the anchor link to strip out after a link like <a class="page-scroll" href="../#contact">Contact</a> on another external page.

I've searched high and low on SO but can't find a solution that works.

I don't totally care about the smooth scrolling if the link is from an external page. What I need most is to navigate / scroll to the id section of the main page (with offset to accommodate fixed navigation) and remove the anchor link from the browser URL window when the link is from an external page (from other pages on my website, or from other websites).

I've tried this also, but it likewise only works on internal links on to an id on the same page :

<script>
$(function() {
  $('a[href*=#]:not([href=#])').click(function() {
    if (location.pathname.replace(/^\//,'') == this.pathname.replace(/^\//,'') && location.hostname == this.hostname) {

      var target = $(this.hash);
      target = target.length ? target : $('[name=' + this.hash.slice(1) +']');
      if (target.length) {
        $('html,body').animate({
          scrollTop: target.offset().top - 60
        }, 1000);
        return false;
      }
    }
  });
});
</script>

I've also tried this with no luck :

    <script type="text/javascript">
(function($) {
    $(document).ready(function() {
    var url=document.URL.split("#");
    var ancher=url[1];
         $('html, body').animate({
           'scrollTop':   $('#'+ancher).offset().top - 60
         }, 5000);
    });
})(jQuery);
  </script>

Any New Year's Eve help would be most appreciated so I can get this project wrapped up!

Alex Wright
  • 192
  • 3
  • 12
  • Are you aware that jQuery's `bind` method has been deprecated since version 1.7? – Robusto Dec 31 '15 at 17:40
  • Thanks Robusto. The script came from one that another person wrote. I need to get on to writing this stuff myself. All in good time. Thank you for the help. – Alex Wright Dec 31 '15 at 17:45
  • Got it to work based heavily on [a solution](http://stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header) by [Ian Clark](http://stackoverflow.com/users/1773904/ian-clark) - THANKS! – Alex Wright Jan 08 '16 at 17:19

2 Answers2

3

It's possible I don't understand the extent of the question, but I believe you are trying to make it so the href doesn't fire on pages that are wanting to scroll but does on pages that are linking to other pages and not sections within the page itself. Perhaps something like this would work for you:

$(function() {
    $('a.page-scroll').bind('click', function(event) {
        var $anchor = $(this);
        if ($anchor[0].href[0] === '#') {
            $('html, body').stop().animate({
                scrollTop: $($anchor.attr('href')).offset().top  - 60
            }, 1000, 'easeInOutExpo');
            event.preventDefault();
            return false;
        } else {
            return true;
        }
    });
});

What this does is look to see that the leading character in the href is a # implying that its a link to a section within itself.

Let me know if that helps and/or if I'm on the right track.

ps: I left the .bind in there because I don't know what version of jQuery you are on, but the newer syntax is to use .on

Happy New Year

Just to append slightly in regards to making it so that deep links to the main page go to the appropriate section but don't have the hash tag:

You can remove that 'hash' variable from window.location, but if you attempt to remove the hashtag entirely, it will cause the browser to refresh. This will also cause the viewer to lose the spot (thus removing the deep link's purpose).

To change the hash tag value (keeps the #):

window.location.hash = ''; // clears the hash tag

To remove the hash tag and its value (clears the # and everything past it):

window.location.href = window.location.href.substr(0, window.location.href.indexOf('#')); // this causes a browser refresh

And if it's not wholly apparent, you would run it on page load

$(document).ready(function() {
    if (typeof(window.location.hash) !== 'undefined' && window.location.hash.length > 0) {
        window.location.hash = ''; // will clear the hash anytime someone arrives with a hash tag
    }
});
Lawrence Johnson
  • 3,924
  • 2
  • 17
  • 30
  • Hi thanks so much for the help and apologies for not being more clear. I have two scenarios. The first, which is working fine using the first jQuerry function listed in the question, is to smooth scroll within the main page from internal / on page links with anchor links removed from the URL in the browser window. The second scenario, which I need help with, is to do the same for links to the main page *from other pages*. So, a link to http://mainpage.com/#contact from http://mainpage.com/subpage would scroll to #contact but show only http://mainpage.com/ in the browser window. – Alex Wright Dec 31 '15 at 20:21
  • And I will remove .bind and replace with .on - thanks for that as well. – Alex Wright Dec 31 '15 at 20:24
  • Here's a link to [the live website](http://alexwright.net) with the issue I'm describing. I'm trying to remove the #what-i-do and #portfolio and #contact anchor links from the browser URL when clicking back to the main page from the navigation of the project / portfolio pages while also setting a 60px offset to the anchor links to make up for the fixed nav. – Alex Wright Dec 31 '15 at 20:30
  • Oh, so what you are trying to do is remove the hash after a user arrives at the page from somewhere else? You are going to have difficulty with that. For instance, you can set window.location.hash = '', but it won't remove the actual hash tag. Removing the actual hash tag will cause the browser to refresh the page. – Lawrence Johnson Dec 31 '15 at 22:20
  • You have to figure that with a true SPA, you never leave the main page. Linking within would still have a sub-page url (like /contact) and it would be up to the SPA engine to remove that (if you wanted). – Lawrence Johnson Dec 31 '15 at 22:21
  • One other thing of note is that the hashtag has no real purpose. For instance, it's never sent to the web server (only querystring params are). In terms of SEO, for instance, it has no meaning. So assuming you just don't want people to copy/paste the link with #contact, the solution setting the window.location.hash = '' should do the trick for you. – Lawrence Johnson Dec 31 '15 at 22:28
  • Thanks so much for your help Lawrence. Perhaps you're right that what I'm looking for isn't possible. I'd like the hashtags / anchor links to be removed from the URL but the navigation to still go to that section of the page, with an offset to make up for the navigation. You're right, I'm looking to amend a SPA / single page website with the ability to have other pages that can link back to the main SPA without carrying the hashtag / anchor link in the url bar. Here's [another SO thread](http://stackoverflow.com/questions/23312006/remove-hashtag-from-url) that somewhat references the issue – Alex Wright Jan 03 '16 at 03:38
  • @AlexWright I'm glad it helped you get closer to your goal. An upvote and/or checkmark would be greatly appreciated. Good luck! – Lawrence Johnson Jan 04 '16 at 01:44
  • Thanks, Lawrence. I'm still working on the issue. I've upvoted your answer and I'll post a solution if I find one. – Alex Wright Jan 04 '16 at 21:59
  • like what you did here -- http://stackoverflow.com/questions/34504260/horizontally-center-video-in-bootstrap/34505001#34505001 -- what a shame. – Lawrence Johnson Jan 04 '16 at 22:40
  • How is that a shame? The answer didn't work. I upvoted the answer, re-worked it, and provided a solution that did work in case it's helpful for anyone else. How is that a problem? – Alex Wright Jan 05 '16 at 14:49
  • Couple things. The answer is not supposed to be someone doing the programming for you. The point of the Q&A system is to show you how something works and provide samples if its helpful so that YOU can make your specific instance work. Taking someone else's answer and adding your specific code makes no sense because it adds no value to anyone but you. Likewise, if the answer to your question is only two possible options because what you want to do isn't possible, then that is the correct answer. Also, I'm not sure what you think upvoting is, but this answer has not been upvoted. – Lawrence Johnson Jan 05 '16 at 17:12
  • Thanks for the feedback. I have upvoted both answers but the upvotes aren't showing due to new account's reputation under the threshold necessary to display upvotes. I'm happy to go back and delete the answer to the other thread you referenced. The thing is, while very helpful, the answer to that questions wasn't correct. Marking it as so isn't helpful to anyone. Yes, parts of it got to the right place. In that case, my understanding was showing what parts worked incorporated into a full answer was helpful to others. – Alex Wright Jan 05 '16 at 18:09
1

For a page with smooth scrolling try to use replaceState().
It will remove the hashtag at anchor link from the browser URL window (without page reloading).

// smooth scrolling
function scrollTo(selectors)
{
    if(!$(selectors).length) return;
    var selector_top = $(selectors).offset().top - 0;
    $('html,body').animate({ scrollTop: selector_top }, 'slow');
}    

// do scroll and clear the hash tag    
$(window).on('load', function(){          
    if( typeof(location.hash) !== 'undefined' && location.hash.length ) {
       scrollTo(location.hash);
       history.replaceState(null, null, location.pathname);                      
    }       
});
eQ19
  • 9,880
  • 3
  • 65
  • 77