Skip to content

Commit a3f5952

Browse files
authored
Merge pull request #1072 from sveltejs/gh-1071
lock scroll bindings to allow tweening
2 parents 6b956fb + 6ccc7b8 commit a3f5952

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

src/generators/nodes/Window.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import CodeBuilder from '../../utils/CodeBuilder';
12
import deindent from '../../utils/deindent';
23
import { stringify } from '../../utils/stringify';
34
import flattenReference from '../../utils/flattenReference';
@@ -106,6 +107,8 @@ export default class Window extends Node {
106107
});
107108

108109
const lock = block.getUniqueName(`window_updating`);
110+
const clear = block.getUniqueName(`clear_window_updating`);
111+
const timeout = block.getUniqueName(`window_updating_timeout`);
109112

110113
Object.keys(events).forEach(event => {
111114
const handlerName = block.getUniqueName(`onwindow${event}`);
@@ -114,10 +117,15 @@ export default class Window extends Node {
114117
if (event === 'scroll') {
115118
// TODO other bidirectional bindings...
116119
block.addVariable(lock, 'false');
120+
block.addVariable(clear, `function() { ${lock} = false; }`);
121+
block.addVariable(timeout);
117122
}
118123

119124
const handlerBody = deindent`
120-
${event === 'scroll' && `${lock} = true;`}
125+
${event === 'scroll' && deindent`
126+
if (${lock}) return;
127+
${lock} = true;
128+
`}
121129
${generator.options.dev && `component._updatingReadonlyProperty = true;`}
122130
123131
#component.set({
@@ -146,14 +154,16 @@ export default class Window extends Node {
146154

147155
block.builders.init.addBlock(deindent`
148156
function ${observerCallback}() {
149-
if (${lock}) return;
157+
${lock} = true;
158+
clearTimeout(${timeout});
150159
var x = ${bindings.scrollX
151160
? `#component.get("${bindings.scrollX}")`
152161
: `window.scrollX`};
153162
var y = ${bindings.scrollY
154163
? `#component.get("${bindings.scrollY}")`
155164
: `window.scrollY`};
156165
window.scrollTo(x, y);
166+
${timeout} = setTimeout(${clear}, 100);
157167
}
158168
`);
159169

@@ -170,8 +180,10 @@ export default class Window extends Node {
170180

171181
block.builders.init.addBlock(deindent`
172182
#component.observe("${bindings.scrollX || bindings.scrollY}", function(${isX ? 'x' : 'y'}) {
173-
if (${lock}) return;
183+
${lock} = true;
184+
clearTimeout(${timeout});
174185
window.scrollTo(${isX ? 'x, window.scrollY' : 'window.scrollX, y'});
186+
${timeout} = setTimeout(${clear}, 100);
175187
});
176188
`);
177189
}

test/js/samples/window-binding-scroll/expected-bundle.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,10 @@ var proto = {
190190

191191
/* generated by Svelte vX.Y.Z */
192192
function create_main_fragment(state, component) {
193-
var window_updating = false, p, text, text_1;
193+
var window_updating = false, clear_window_updating = function() { window_updating = false; }, window_updating_timeout, p, text, text_1;
194194

195195
function onwindowscroll(event) {
196+
if (window_updating) return;
196197
window_updating = true;
197198

198199
component.set({
@@ -203,8 +204,10 @@ function create_main_fragment(state, component) {
203204
window.addEventListener("scroll", onwindowscroll);
204205

205206
component.observe("y", function(y) {
206-
if (window_updating) return;
207+
window_updating = true;
208+
clearTimeout(window_updating_timeout);
207209
window.scrollTo(window.scrollX, y);
210+
window_updating_timeout = setTimeout(clear_window_updating, 100);
208211
});
209212

210213
return {

test/js/samples/window-binding-scroll/expected.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
import { appendNode, assign, createElement, createText, detachNode, init, insertNode, proto } from "svelte/shared.js";
33

44
function create_main_fragment(state, component) {
5-
var window_updating = false, p, text, text_1;
5+
var window_updating = false, clear_window_updating = function() { window_updating = false; }, window_updating_timeout, p, text, text_1;
66

77
function onwindowscroll(event) {
8+
if (window_updating) return;
89
window_updating = true;
910

1011
component.set({
@@ -15,8 +16,10 @@ function create_main_fragment(state, component) {
1516
window.addEventListener("scroll", onwindowscroll);
1617

1718
component.observe("y", function(y) {
18-
if (window_updating) return;
19+
window_updating = true;
20+
clearTimeout(window_updating_timeout);
1921
window.scrollTo(window.scrollX, y);
22+
window_updating_timeout = setTimeout(clear_window_updating, 100);
2023
});
2124

2225
return {

0 commit comments

Comments
 (0)