swup / scroll-plugin

A swup plugin for smooth scrolling 🏄‍♂️

Home Page:https://swup.js.org/plugins/scroll-plugin

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Disable smooth scroll for certain links

MikeHarrison opened this issue · comments

Hi,

Loving the new plugin setup, got upgraded from v1 and sorted really quickly. Just one outstanding issue, I am using the smooth scroll plugin on the site, but don't want to use it for some specific links. This is the code I used to achieve this with v1:

// Don't smooth scroll gallery filter links

  var galleryLink = document.querySelectorAll('a.filter-link');

  for (var i = 0, len = galleryLink.length; i < len; i++) {
    galleryLink[i].addEventListener('click', function(){
      swup.options.scroll = false;
    });
  }

document.addEventListener('swup:animationInDone', function() {
    swup.options.scroll = true;
});

What is the best option in Swup v2 for excluding specific links from the scroll behaviour?

Thanks - really enjoying working with Swup :)

Or would it be possible to add an option to add something like data-swup-no-scroll to the link?

Has anyone got any thoughts on this? It would be good to work out an approach to match the functionality I had in Swup 1

Hey 👋 , sorry for the late reply!

You can do the same with Swup v2, the only difference is that you need to change the option in the plugin instance. findPlugin should help with that.

swup.findPlugin('ScrollPlugin');

will return the plugin instance, where you can change the animateScroll option as you like.

No worries!

Thanks for the pointer - that didn't do quite what I was after (it stopped the scroll being animated, but still set the scroll position to the top of the page).

But I found what I was looking for when I did some reading about the findPlugin method. I ended up doing this:

// Don't smooth scroll gallery filter links

  var galleryLink = document.querySelectorAll('a.filter-link');

  for (var i = 0, len = galleryLink.length; i < len; i++) {
    galleryLink[i].addEventListener('click', function(){
      swup.unuse('ScrollPlugin');
    });
  }

document.addEventListener('swup:animationInDone', function() {
    swup.use('ScrollPlugin');
});

This seems to work well for what I wanted (page content replaced but scroll position staying the same), but if there is a better approach I would be interested to hear it.

Ah no that doesn't work actually 😞

When the page reloads after clicking on a galleryLink the scroll position remains the same 👍 but after that the scroll plugin doesn't work for normal links 👎 .

I get the following error in the console: Not swup plugin instance ScrollPlugin.

Any thoughts Georgy? It's got me stumped

use method doesn't accept a string, it accepts a plugin instance. https://swup.js.org/plugins

Thanks for the tip, my code now looks like this:

// Don't smooth scroll gallery filter links

  var galleryLink = document.querySelectorAll('a.filter-link');

  for (var i = 0, len = galleryLink.length; i < len; i++) {
    galleryLink[i].addEventListener('click', function(){
      swup.unuse('ScrollPlugin');
    });
  }

document.addEventListener('swup:animationInDone', function() {
    swup.use(new SwupScrollPlugin());
});

This is now behaving exactly as I would like it to, smooth scrolling all links except those with a class of .filter-link. Also smooth scroll resumes after clicking on a filter-link for any other links. Super.

My only concern is I am now getting a console error:

triggerEvent.js:12

TypeError: e.scrollTo is not a function
    at e.i.doScrolling (index.js:74)
    at i.onContentReplaced (index.js:56)
    at triggerEvent.js:10
    at Array.forEach (<anonymous>)
    at t [as _triggerEvent] (triggerEvent.js:8)
    at t.s.triggerEvent (index.js:44)
    at t [as renderPage] (renderPage.js:46)
    at loadPage.js:104

This doesn't seem to be affecting anything, but not sure if I should be worried about it or not! It occurs when clicking on one of the filter-link links, and looking in the debug it happens here:

index.js:37 swup:clickLink
index.js:41 swup:transitionStart
index.js:41 swup:animationOutStart
index.js:41 swup:pageRetrievedFromCache
index.js:41 swup:animationOutDone
index.js:41 swup:willReplaceContent
index.js:41 swup:contentReplaced
index.js:53 Executed 0 scripts.
-----> ERROR HERE
index.js:41 swup:pageView
index.js:41 swup:animationInStart
index.js:41 swup:animationInDone
index.js:41 swup:transitionEnd

im trying to remove the scroll from a slider dotnav too.
cant add data-no-swup through html, tried $('.uk-dotnav > li > a').attr('data-no-swup',''); but it only works on first load (when putting it into an init() function called with swup.on('contentReplaced', init);, it doesnt work for loaded pages)

@MikeHarrison's code give me No such plugin. on the unuse line (being called inside init().

  var galleryLink = document.querySelectorAll('.uk-dotnav > li > a');
  for (var i = 0, len = galleryLink.length; i < len; i++) {
    galleryLink[i].addEventListener('click', function(){
      swup.unuse('ScrollPlugin');
    });
  }

Any news on this?

actually managed to add data-no-swup to the links instead with

var dotnavFix = document.querySelectorAll(".uk-dotnav li a");
  dotnavFix.forEach(function(el){
    el.setAttribute("data-no-swup", "");
  });

in the init() and on a document.addEventListener('swup:animationInDone', function() { function.

commented

updated workaround to disable scrolling on certain links:

<a href="/link-that-should-not-scroll" data-no-scroll="">Hi</a>
swup.on('clickLink', click => {
    if(click.delegateTarget.hasAttribute('data-no-scroll')) {
        swup.unuse('ScrollPlugin');
    };
})

swup.on('animationInDone', () => {
    swup.use(new SwupScrollPlugin({
        // your options here
    }));
})

would be great if the plugin had an ìgnore' option, without needing to disable the plugin entirely. that way you could still use the scrollTo method for custom scroll behavior

edit: seems to cause some sort of race condition and doesn't work all the time... might create new issue