diff --git a/packages/svelte/src/internal/client/dom/elements/attributes.js b/packages/svelte/src/internal/client/dom/elements/attributes.js index 08b6704a17..5065ce7951 100644 --- a/packages/svelte/src/internal/client/dom/elements/attributes.js +++ b/packages/svelte/src/internal/client/dom/elements/attributes.js @@ -2,7 +2,7 @@ import { DEV } from 'esm-env'; import { hydrating } from '../hydration.js'; import { get_descriptors, get_prototype_of, map_get, map_set } from '../../utils.js'; import { AttributeAliases, DelegatedEvents, namespace_svg } from '../../../../constants.js'; -import { delegate } from './events.js'; +import { create_event, delegate } from './events.js'; import { autofocus } from './misc.js'; import { effect, effect_root } from '../../reactivity/effects.js'; import * as w from '../../warnings.js'; @@ -150,9 +150,13 @@ export function set_attributes(element, prev, next, lowercase_attributes, css_ha if (value != null) { if (!delegated) { if (!prev) { - events.push([key, value, () => element.addEventListener(event_name, value, opts)]); + events.push([ + key, + value, + () => (next[key] = create_event(event_name, element, value, opts)) + ]); } else { - element.addEventListener(event_name, value, opts); + next[key] = create_event(event_name, element, value, opts); } } else { // @ts-ignore diff --git a/packages/svelte/src/internal/client/dom/elements/events.js b/packages/svelte/src/internal/client/dom/elements/events.js index b030996fbc..bb844fcd5a 100644 --- a/packages/svelte/src/internal/client/dom/elements/events.js +++ b/packages/svelte/src/internal/client/dom/elements/events.js @@ -6,18 +6,14 @@ import { define_property, is_array } from '../../utils.js'; * @param {string} event_name * @param {Element} dom * @param {EventListener} handler - * @param {boolean} capture - * @param {boolean} [passive] - * @returns {void} + * @param {AddEventListenerOptions} options */ -export function event(event_name, dom, handler, capture, passive) { - var options = { capture, passive }; - +export function create_event(event_name, dom, handler, options) { /** * @this {EventTarget} */ function target_handler(/** @type {Event} */ event) { - if (!capture) { + if (!options.capture) { // Only call in the bubble phase, else delegated events would be called before the capturing events handle_event_propagation(dom, event); } @@ -28,6 +24,21 @@ export function event(event_name, dom, handler, capture, passive) { dom.addEventListener(event_name, target_handler, options); + return target_handler; +} + +/** + * @param {string} event_name + * @param {Element} dom + * @param {EventListener} handler + * @param {boolean} capture + * @param {boolean} [passive] + * @returns {void} + */ +export function event(event_name, dom, handler, capture, passive) { + var options = { capture, passive }; + var target_handler = create_event(event_name, dom, handler, options); + // @ts-ignore if (dom === document.body || dom === window || dom === document) { render_effect(() => {