Skip to content
This repository has been archived by the owner on Apr 28, 2020. It is now read-only.

Enable smooth-scroll for links to other pages #54

Closed
JonasHavers opened this issue Mar 22, 2014 · 22 comments
Closed

Enable smooth-scroll for links to other pages #54

JonasHavers opened this issue Mar 22, 2014 · 22 comments

Comments

@JonasHavers
Copy link
Contributor

Hey Chris.

Currently, smooth-scroll just works for on-page links. What about adding the possibility to link to different url paths and invoking the scroll animation with the on body load event if a hash (and some additional identifier) is present in the url? This way you could use the same links on multiple pages, e.g. in a navigation.

An example link: /imprint/#.privacy
If the link points to another page, is marked with data-scroll and the hash is present in the url, smooth-scroll would invoke the animation and scroll to the element with the id or class "privacy" on page load event. As for a link to an element on the current page, you should still invoke the animation on the click event. The check could be done using window.location.pathname in this case. If you just use the hash without the additional dot, of course, the browser directly jumps to the element with the id "privacy". So I think you need an additional identifier after the hash which is removed, replaced or interpreted as the class identifier to be used to select the element on the page via the querySelector.

What do you think?

@cferdinandi
Copy link
Owner

Use cases like this are why I chose to expose the animateScroll function. I feel functionality like this is more of an edge case than the norm, and would rather see devs expand Smooth Scroll for this than add it to the core.

Example:

document.addEventListener('DOMContentLoaded', function() {
    if ( window.location.hash ) {
        smoothScroll.animateScroll(  null, window.location.hash  );
    }
});

One simply runs that on page load.

@aaParis
Copy link

aaParis commented Mar 25, 2014

Hi: Great script!
I'm a JS newbie and use smoothScroll to navigate my DIV's,.
I would like to implerment the smoothscroll script also for page on-load.

as i am really bad in JS,,,,,,,,,,
my tag is a div named #index and the offset i use is -200px;

so i would put in the body section:
body onload=‘ smoothScroll ( window.location.href="#index".offset="-200" ) ‘

then in the head section;
script type="application/javascript">
document.addEventListener('DOMContentLoaded', function() {
If ( window.location.hash ) {
smoothScroll.animateScroll( null, window.location.hash.offset );
}
});

@yonelacort
Copy link

The code posted here didn't make the job for me.
In case someone still experiences the same problem, this worked for me:

  $(document).ready(function() {
   smoothScroll.init();
    $("a").click(function() {
      var regExp = new RegExp(/\/\/.+?(\/.+?)\#/);
      if ( window.location.hash && window.location.pathname != regExp.exec(this.href)[1]) {
        window.location.href = this.href;
      }
    });
  });

@shofer4eto
Copy link

Hi there,

Great plugin, thanks! :)
I have implemented the smoothScroll.animateScroll for scenarios when coming from a different page and and all works fine when I remove the [data-scroll] attribute for links to different pages.
The problem is I am using the plugin in a WP theme where Menus are created globally so you have to add have the [data-scroll] attribute for the case when your link takes you to the current page and then you need to have it removed for when one a different page. Do I write a custom JS method that should crawl my document to see if there are sections with the anchor ID and then remove the [data-scroll] attribute if not, thus it knows the link is to another page and not generate the error:

Uncaught TypeError: Cannot read property 'offsetParent' of null

or is there an easier way to tackle this?
Thanks!

@cferdinandi
Copy link
Owner

@shofer4eto

Do you have a link or demo page I can look at? If it were me, personally, I would take one of two approaches.

Option 1

Use a custom WordPress walker function to crawl the wp_nav_menu() method and the data-scroll attribute to links pointing to the existing page.

Option 2

Easier, and the one I'd probably go with:

  1. Get an array of all nav menu links that point to the current page AND have a hash: document.querySelectorAll( '.YOUR-MENU-CLASS .current-menu-item a[href^="#"]' )
  2. Loop through those links and add the data-scroll attribute.

If there's only one per page, it's even easier:

var link = document.querySelector( '.YOUR-MENU-CLASS .current-menu-item a[href^="#"]'  );
if ( link ) {
    link.setAttribute( 'data-scroll', true );
}

@shofer4eto
Copy link

Hi there,

Thanks for the response!
Yes, here's a great example:

http://www.ideadigital.com.ve/

When on the Home page click on the menu in the footer (3rd column). Works like a charm.
Then go to the blog for example:

http://www.ideadigital.com.ve/nuestro-blog/

The Menu in the footer generates a "Uncaught TypeError: Cannot read property 'offsetParent' of null" error.
The problem is the footer menu items have the full Home page + /#SectionID and when setting up the menu in the Admin I do not know if the user is on the current (Home) page or not. I actually use a custom selector (can't really add custom attributes in WP admin, you can add a "rel" attribute with a value though).

Here's my JS:

smoothScroll.init({
    selector: '[rel="smooth_scroll"]',
    selectorHeader: '#header.sticky_header', // Selector for fixed headers
    speed: 500, 
    easing: 'easeInOutQuart',
    updateURL: false,
    offset: 0,
});

if ( window.location.hash ) {
        var options = {
        speed: 800, 
        easing: 'easeInOutQuart',
    };
        smoothScroll.animateScroll( null, window.location.hash, options );
     }

WDYT? Thanks again for your time! :)

@cferdinandi
Copy link
Owner

For those, I would remove the rel="smooth-scroll" altogether, and let this do it's thing:

if ( window.location.hash ) {
        var options = {
        speed: 800, 
        easing: 'easeInOutQuart',
    };
        smoothScroll.animateScroll( null, window.location.hash, options );
     }

@cferdinandi
Copy link
Owner

Also, you're the first person I've seen using the new custom selector option. Cool to see it in the wild!

@shofer4eto
Copy link

I pass the rel="smooth-scroll" part in order to initialize the smoothscroll for those specific menu items. If I leave it out they won't smooth scroll to the corresponding sections, instead just link normally.

@cferdinandi
Copy link
Owner

@shofer4eto I thought these were always linking to new pages? Oh, I see what you mean. Sometimes they will be linking to the page the visitor is already on!

If it were me, I'd remove rel="smooth-scroll", and then use JavaScript to dynamically add it only to links for the current page. This needs to be worked on a bit, but something like this:

var navs = document.querySelectorAll('#menu-menu-footer a[href*="' + location.pathname + '"]');
for (var i = 0, len = navs.length; i < len; i++) {
    navs[i].setAttribute( 'rel', 'smooth-scroll' );
}

@shofer4eto
Copy link

Hi again,

Yes, sounds like a good idea, but the functionality to add regular Smooth Scroll links on a page should also be preserved...
So maybe I should crawl the whole document tree for links that have the rel="smooth-scroll", then check if those nodes point to the current page and only then initialize Smooth scroll for them? WDYT?

@cferdinandi
Copy link
Owner

@shofer4eto I would add rel="smooth-scroll" to the links you know are local, and use some version of that script to dynamically add them to other stuff. Smooth Scroll can't be initialized on a link-by-link basis, so your suggested approach wouldn't work.

FWIW, WordPress DOES provide mechanisms for dynamically adding content based on whether or not you're on the same page as the link, but it would require you to muck around in the functions.php file, and it gets weird and messy.

@shofer4eto
Copy link

@cferdinandi,

I would add the rel="smooth-scroll" to the links in normal Page content, yes, and again for the Menus I have to add it globally. And the suggestion should work because I would do the crawling ondocument.ready prior to initializing the Smoothscroll, then leave out the rel="smooth-scroll"attribute only if the menu link is pointing to the current page.

I really want ot stay away from the WP Walker_Nav_Menu methods too...

@cferdinandi
Copy link
Owner

It actually doesn't matter when you initialize smooth scroll. It checks to see if you've clicked a smooth scroll link whenever you click an element on the page, so you can add links after init and they'll still work.

@shofer4eto
Copy link

Oh, ok then... what's your objection to my approach not working then? :)

@cferdinandi
Copy link
Owner

No objection. Just letting you know.

@shofer4eto
Copy link

I meant here:

'@shofer4eto I would add rel="smooth-scroll" to the links you know are local, and use some version of that script to dynamically add them to other stuff. Smooth Scroll can't be initialized on a link-by-link basis, so your suggested approach wouldn't work.'

@shofer4eto
Copy link

Anyway, I'll just get to playing around with this tomorrow and see if I can manage it.
Thanks a lot for your time, it's great to see active support for your awesome plugin! Good job! :)

@ghost
Copy link

ghost commented Aug 23, 2019

I've tried variations to get this working but no success...I just want to direct to another page and then scroll down to that section....

<a href="/about#staff_members" aria-current="page" data-scroll="true">Meet the team</a>

data-scroll = true and I have this in my .js file;

var scroll = new SmoothScroll('a[href*="#"]'); smoothScroll.init(); jQuery("a").click(function() { var regExp = new RegExp(/\/\/.+?(\/.+?)\#/); if ( window.location.hash && window.location.pathname != regExp.exec(this.href)[1]) { window.location.href = this.href; } });

Yet all I get back is;

Uncaught ReferenceError: smoothScroll is not defined

@cferdinandi
Copy link
Owner

What you’re trying to do only works with the native CSS approach. SmoothScroll doesn’t work for anchors on page load.

@ghost
Copy link

ghost commented Aug 23, 2019

Hi @cferdinandi thanks for getting back to me, sorry I must've read the convo above wrong then....

When you say native CSS approach - how do you mean? I can't think how CSS could help when directing to another page and then scrolling to that section...? Thanks

@cferdinandi
Copy link
Owner

A newish addition to the docs:

Quick aside: you might not need this library. There's a native CSS way to handle smooth scrolling that might fit your needs.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants