diff --git a/.changeset/famous-mirrors-count.md b/.changeset/famous-mirrors-count.md new file mode 100644 index 000000000000..78e6011629ed --- /dev/null +++ b/.changeset/famous-mirrors-count.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: align list of passive events with browser defaults diff --git a/documentation/docs/02-template-syntax/02-basic-markup.md b/documentation/docs/02-template-syntax/02-basic-markup.md index b8e263231951..8bf9b2cf42a0 100644 --- a/documentation/docs/02-template-syntax/02-basic-markup.md +++ b/documentation/docs/02-template-syntax/02-basic-markup.md @@ -112,6 +112,10 @@ Because events are just attributes, the same rules as for attributes apply: Timing-wise, event attributes always fire after events from bindings (e.g. `oninput` always fires after an update to `bind:value`). Under the hood, some event handlers are attached directly with `addEventListener`, while others are _delegated_. +When using `onwheel`, `onmousewheel`, `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`. + +In the very rare cases that you need to prevent these event defaults, you should use [`on`](https://svelte-5-preview.vercel.app/docs/imports#svelte-events) instead (for example inside an action). + ### Event delegation To reduce memory footprint and increase performance, Svelte uses a technique called event delegation. This means that for certain events — see the list below — a single event listener at the application root takes responsibility for running any handlers on the event's path. diff --git a/packages/svelte/src/utils.js b/packages/svelte/src/utils.js index bf241c7947c2..289a9523de49 100644 --- a/packages/svelte/src/utils.js +++ b/packages/svelte/src/utils.js @@ -222,7 +222,7 @@ export function is_dom_property(name) { return DOM_PROPERTIES.includes(name); } -const PASSIVE_EVENTS = ['wheel', 'touchstart', 'touchmove', 'touchend', 'touchcancel']; +const PASSIVE_EVENTS = ['wheel', 'mousewheel', 'touchstart', 'touchmove']; /** * Returns `true` if `name` is a passive event diff --git a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md index ebf8f91e805e..a4149292031a 100644 --- a/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md +++ b/sites/svelte-5-preview/src/routes/docs/content/03-appendix/02-breaking-changes.md @@ -238,6 +238,12 @@ This is [no longer true in Svelte 5](/#H4sIAAAAAAAAE4WQwU7DMAyGX8VESANpXe8lq9Q8A ``` +### Touch and wheel events are passive + +When using `onwheel`, `onmousewheel`, `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) to align with browser defaults. This greatly improves responsiveness by allowing the browser to scroll the document immediately, rather than waiting to see if the event handler calls `event.preventDefault()`. + +In the very rare cases that you need to prevent these event defaults, you should use [`on`](https://svelte-5-preview.vercel.app/docs/imports#svelte-events) instead (for example inside an action). + ## Other breaking changes ### Stricter `@const` assignment validation