Skip to content
This repository was archived by the owner on Jan 11, 2023. It is now read-only.

Commit 42fc0fb

Browse files
authored
Add noscroll option to goto and rename sapper-noscroll (#1320)
1 parent ef9af74 commit 42fc0fb

File tree

6 files changed

+65
-5
lines changed

6 files changed

+65
-5
lines changed

runtime/src/app/goto/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { history, select_target, navigate, cid } from '../app';
22

3-
export default function goto(href: string, opts = { replaceState: false }) {
3+
export default function goto(href: string, opts = { noscroll: false, replaceState: false }) {
44
const target = select_target(new URL(href, document.baseURI));
55

66
if (target) {
77
history[opts.replaceState ? 'replaceState' : 'pushState']({ id: cid }, '', href);
8-
return navigate(target, null).then(() => {});
8+
return navigate(target, null, opts.noscroll).then(() => {});
99
}
1010

1111
location.href = href;

runtime/src/app/start/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function handle_click(event: MouseEvent) {
110110

111111
const target = select_target(url);
112112
if (target) {
113-
const noscroll = a.hasAttribute('sapper-noscroll');
113+
const noscroll = a.hasAttribute('sapper:noscroll');
114114
navigate(target, null, noscroll, url.hash);
115115
event.preventDefault();
116116
history.pushState({ id: cid }, '', url.href);

site/content/docs/03-client-api.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ sapper.start({
2727
### goto(href, options?)
2828

2929
* `href` — the page to go to
30-
* `options` — can include a `replaceState` property, which determines whether to use `history.pushState` (the default) or `history.replaceState`. Not required
30+
* `options` — not required
31+
* `replaceState` (`boolean`, default `false`) — determines whether to use `history.pushState` (the default) or `history.replaceState`.
32+
* `noscroll` (`boolean`, default `false`) — prevent scroll to top after navigation.
3133

3234
Programmatically navigates to the given `href`. If the destination is a Sapper route, Sapper will handle the navigation, otherwise the page will be reloaded with the new `href`. In other words, the behaviour is as though the user clicked on a link with this `href`.
3335

site/content/docs/08-link-options.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,15 @@ Adding a `rel=external` attribute to a link...
3131
```
3232

3333
...will trigger a browser navigation when the link is clicked.
34+
35+
### sapper:noscroll
36+
37+
When navigating to internal links, Sapper will change the scroll position to 0,0 so that the user is at the very top left of the page. When a hash is defined, it will scroll to the element with a matching ID.
38+
39+
In certain cases, you may wish to disable this behaviour. Adding a `sapper:noscroll` attribute to a link...
40+
41+
```html
42+
<a href='path' sapper:noscroll>Path</a>
43+
```
44+
45+
...will prevent scrolling after the link is clicked.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<script>
2+
import { goto } from "@sapper/app";
3+
4+
function preserveScroll() {
5+
goto("/a-third-tall-page", { noscroll: true });
6+
}
7+
8+
function scroll() {
9+
goto("/a-third-tall-page");
10+
}
11+
</script>
12+
13+
<h1>A search form</h1>
14+
15+
<div style="height: 9999px" />
16+
17+
<div id="search">
18+
<button id="scroll" on:click={scroll}>Don't preserve scroll</button>
19+
<button id="preserve" on:click={preserveScroll}>Preserve scroll</button>
20+
</div>

test/apps/scroll/test.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,33 @@ describe('scroll', function() {
9999
const secondScrollY = await r.page.evaluate(() => window.scrollY);
100100

101101
assert.equal(firstScrollY, secondScrollY);
102-
});
102+
});
103+
104+
it('scrolls to the top when navigating with goto', async () => {
105+
await r.load(`/search-form#search`);
106+
await r.sapper.start();
107+
108+
let initialScrollY = await r.page.evaluate(() => window.scrollY);
109+
assert.ok(initialScrollY > 0, String(initialScrollY));
110+
111+
await r.page.click(`button#scroll`);
112+
113+
let scrollY = await r.page.evaluate(() => window.scrollY);
114+
assert.ok(scrollY === 0, String(scrollY));
115+
});
116+
117+
it('preserves scroll when noscroll: true is passed to goto', async () => {
118+
await r.load(`/search-form#search`);
119+
await r.sapper.start();
120+
121+
let initialScrollY = await r.page.evaluate(() => window.scrollY);
122+
assert.ok(initialScrollY > 0, String(initialScrollY));
123+
124+
await r.page.click(`button#preserve`);
125+
126+
let scrollY = await r.page.evaluate(() => window.scrollY);
127+
assert.ok(scrollY === initialScrollY, String(scrollY));
128+
});
103129

104130
it('survives the tests with no server errors', () => {
105131
assert.deepEqual(r.errors, []);

0 commit comments

Comments
 (0)