diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/input.js b/packages/svelte/src/internal/client/dom/elements/bindings/input.js index 7af20b932a..e528d1699e 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/input.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/input.js @@ -1,6 +1,6 @@ import { DEV } from 'esm-env'; import { render_effect, teardown } from '../../../reactivity/effects.js'; -import { listen_to_event_and_reset_event } from './shared.js'; +import { listen_to_event_and_reset_event, without_reactive_context } from './shared.js'; import * as e from '../../../errors.js'; import { is } from '../../../proxy.js'; import { queue_micro_task } from '../../task.js'; diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/shared.js b/packages/svelte/src/internal/client/dom/elements/bindings/shared.js index 195eae2200..832b7f45e5 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/shared.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/shared.js @@ -1,4 +1,10 @@ import { teardown } from '../../../reactivity/effects.js'; +import { + active_effect, + active_reaction, + set_active_effect, + set_active_reaction +} from '../../../runtime.js'; import { add_form_reset_listener } from '../misc.js'; /** @@ -25,6 +31,23 @@ export function listen(target, events, handler, call_handler_immediately = true) }); } +/** + * @template T + * @param {() => T} fn + */ +export function without_reactive_context(fn) { + var previous_reaction = active_reaction; + var previous_effect = active_effect; + set_active_reaction(null); + set_active_effect(null); + try { + return fn(); + } finally { + set_active_reaction(previous_reaction); + set_active_effect(previous_effect); + } +} + /** * Listen to the given event, and then instantiate a global form reset listener if not already done, * to notify all bindings when the form is reset @@ -34,7 +57,7 @@ export function listen(target, events, handler, call_handler_immediately = true) * @param {() => void} [on_reset] */ export function listen_to_event_and_reset_event(element, event, handler, on_reset = handler) { - element.addEventListener(event, handler); + element.addEventListener(event, () => without_reactive_context(handler)); // @ts-expect-error const prev = element.__on_r; if (prev) { diff --git a/packages/svelte/src/internal/client/dom/elements/bindings/window.js b/packages/svelte/src/internal/client/dom/elements/bindings/window.js index 61775b9d4b..2f7e44c5d9 100644 --- a/packages/svelte/src/internal/client/dom/elements/bindings/window.js +++ b/packages/svelte/src/internal/client/dom/elements/bindings/window.js @@ -1,5 +1,5 @@ import { effect, render_effect, teardown } from '../../../reactivity/effects.js'; -import { listen } from './shared.js'; +import { listen, without_reactive_context } from './shared.js'; /** * @param {'x' | 'y'} type @@ -10,13 +10,14 @@ import { listen } from './shared.js'; export function bind_window_scroll(type, get, set = get) { var is_scrolling_x = type === 'x'; - var target_handler = () => { - scrolling = true; - clearTimeout(timeout); - timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?) + var target_handler = () => + without_reactive_context(() => { + scrolling = true; + clearTimeout(timeout); + timeout = setTimeout(clear, 100); // TODO use scrollend event if supported (or when supported everywhere?) - set(window[is_scrolling_x ? 'scrollX' : 'scrollY']); - }; + set(window[is_scrolling_x ? 'scrollX' : 'scrollY']); + }); addEventListener('scroll', target_handler, { passive: true @@ -61,5 +62,5 @@ export function bind_window_scroll(type, get, set = get) { * @param {(size: number) => void} set */ export function bind_window_size(type, set) { - listen(window, ['resize'], () => set(window[type])); + listen(window, ['resize'], () => without_reactive_context(() => set(window[type]))); } diff --git a/packages/svelte/src/internal/client/dom/elements/events.js b/packages/svelte/src/internal/client/dom/elements/events.js index 12108b00f8..f2038f96ad 100644 --- a/packages/svelte/src/internal/client/dom/elements/events.js +++ b/packages/svelte/src/internal/client/dom/elements/events.js @@ -11,6 +11,7 @@ import { set_active_effect, set_active_reaction } from '../../runtime.js'; +import { without_reactive_context } from './bindings/shared.js'; /** @type {Set} */ export const all_registered_events = new Set(); @@ -61,17 +62,9 @@ export function create_event(event_name, dom, handler, options) { handle_event_propagation.call(dom, event); } if (!event.cancelBubble) { - var previous_reaction = active_reaction; - var previous_effect = active_effect; - - set_active_reaction(null); - set_active_effect(null); - try { + return without_reactive_context(() => { return handler.call(this, event); - } finally { - set_active_reaction(previous_reaction); - set_active_effect(previous_effect); - } + }); } }