Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ability to prevent scrollBehavior on a particular <router-link> #2921

Closed
tmorehouse opened this issue Sep 7, 2019 · 3 comments
Closed

Ability to prevent scrollBehavior on a particular <router-link> #2921

tmorehouse opened this issue Sep 7, 2019 · 3 comments

Comments

@tmorehouse
Copy link

tmorehouse commented Sep 7, 2019

What problem does this feature solve?

In some situations, when one is just changing the hash (or query) the current page scrolls to top (or not quite to the right position). It would be nice to disable the scrollBehavior when users click on a specific <router-link>.

Use case: when controlling tabbed content on a page, clicking the link should change the URL, but the user browser view shouldn't be scrolled (as the tabbed content just updates, and the user should remain at their current scroll position).

I know this is possible with a custom scrollBehaviour() method, but it tends to make the app maintenance a bit more complex when adding new tabbed content sections in a document.

What does the proposed API look like?

Possibly a new Boolean prop prevent-scroll on <router-link>, which when set would disable the scrollBehavior when users click on the <router-link> (specifically for when only the hash or query changes), or an optional property in the location object passed to <router-link>.

@posva
Copy link
Member

posva commented Sep 9, 2019

I think adding a custom scrollBehavior is a very reasonable maintenance cost for such a feature. It can be achieved with the meta property on the routes that need the feature and then checking it in the scrollBehavior method:

scrollBehavior(to, from, savedPosition) {
  if (to.meta.noScroll) return
  // rest of the code
}

It's not added to typings though, so I will add that, but we can return null or undefined` to prevent any scroll.

I don't think adding more props to router-link is the way to go here. This is one of the use cases for history.state that we currently do not support

@posva posva closed this as completed in 5118824 Sep 9, 2019
@jdnz
Copy link

jdnz commented Jan 11, 2023

@posva would it be possible to reconsider something along these lines? I have a couple of use cases where it would be good to have control over scrollBehavior for individual navigations (rather than at the route level through the meta parameter as you suggest). I think an ideal solution would be to pass an object that would override the output of the scrollBehaviour function of the router, e.g. router.push({ name: routeName, scrollBehavior: { el, top }}) .

First use case: Changing hash in the url as user scrolls
In this case I want to update the url using an intersection observer to show a hash according to the where the user is on the page. I can do so using router.replace with a hash, but this causes unwanted scrolling. I could set meta.noScroll as you say for the route, but this would prevent scrolling to the the anchor when someone links to the route with the hash. Ideally I would like to do router.replace({ hash, scrollBehavior: {}) to prevent any scrolling on the url rewrite. Having this option would provide an easy solution to the related issue #2072.

Second use case: Scrolling to the top of a table on pagination
I have a webpage where there is some descriptive content above a table of search results that has pagination. When the user scolls down to the bottom of the search results there is a link to the next page of search results. Clicking this link loads the next page of search results and I want to scroll the page to the top of the table rather than the top of the page, so the user sees directly the new results. However if someone loads the second page of results directly for some reason I would like them to start at the top of the page, so setting the scrollTop at the route level doesn't work.

My current workaround is to have a scrollBehavior object in my state which I set on particular navigation events and then read that in the scrollBehavior function. Being able to set it directly in the navagation would be much simpler and provide a lot more flexibility with scrolling.

@9mm
Copy link

9mm commented Apr 25, 2023

@jdnz this is a pain I agree. "route level" doesnt work for me. the hacky way i did it is adding ns=1 to the URL using the query string and then ignoring scroll if thats there. That way I can do it at the router-link level.

      const resultParams = {
        page: currentPage.value,
        per_page: perPage.value,
        ...filtersActiveQuery.value,
        ns: 1, // see scrollBehavior in router
      };
      router.push({ name: route.name, query: resultParams });

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

No branches or pull requests

4 participants