diff --git a/.changeset/new-baboons-fetch.md b/.changeset/new-baboons-fetch.md new file mode 100644 index 0000000000..f70b82ed37 --- /dev/null +++ b/.changeset/new-baboons-fetch.md @@ -0,0 +1,5 @@ +--- +'svelte': patch +--- + +fix: don't make wheel events passive by default diff --git a/documentation/docs/02-template-syntax/02-basic-markup.md b/documentation/docs/02-template-syntax/02-basic-markup.md index 8bf9b2cf42..437e59eb14 100644 --- a/documentation/docs/02-template-syntax/02-basic-markup.md +++ b/documentation/docs/02-template-syntax/02-basic-markup.md @@ -112,7 +112,7 @@ 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()`. +When using `ontouchstart` and `ontouchmove` event attributes, the handlers are [passive](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#using_passive_listeners) for better performance. 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). diff --git a/packages/svelte/src/utils.js b/packages/svelte/src/utils.js index 289a9523de..60ec364e6f 100644 --- a/packages/svelte/src/utils.js +++ b/packages/svelte/src/utils.js @@ -222,7 +222,16 @@ export function is_dom_property(name) { return DOM_PROPERTIES.includes(name); } -const PASSIVE_EVENTS = ['wheel', 'mousewheel', 'touchstart', 'touchmove']; +/** + * Subset of delegated events which should be passive by default. + * These two are already passive via browser defaults on window, document and body. + * But since + * - we're delegating them + * - they happen often + * - they apply to mobile which is generally less performant + * we're marking them as passive by default for other elements, too. + */ +const PASSIVE_EVENTS = ['touchstart', 'touchmove']; /** * Returns `true` if `name` is a passive event