diff --git a/packages/alpinejs/src/utils/on.js b/packages/alpinejs/src/utils/on.js index d877d87c9..0e9abf630 100644 --- a/packages/alpinejs/src/utils/on.js +++ b/packages/alpinejs/src/utils/on.js @@ -14,11 +14,14 @@ export default function on (el, event, modifiers, callback) { if (modifiers.includes("dot")) event = dotSyntax(event) if (modifiers.includes('camel')) event = camelCase(event) - if (modifiers.includes('passive')) options.passive = true if (modifiers.includes('capture')) options.capture = true if (modifiers.includes('window')) listenerTarget = window if (modifiers.includes('document')) listenerTarget = document + if (modifiers.includes('passive')) { + options.passive = modifiers[modifiers.indexOf('passive')+1] !== 'false' + } + // By wrapping the handler with debounce & throttle first, we ensure that the wrapping logic itself is not // throttled/debounced, only the user's callback is. This way, if the user expects // `e.preventDefault()` to happen, it'll still happen even if their callback gets throttled. @@ -73,7 +76,7 @@ export default function on (el, event, modifiers, callback) { if (isListeningForASpecificKeyThatHasntBeenPressed(e, modifiers)) { return } - + next(e) }) } diff --git a/packages/docs/src/en/directives/on.md b/packages/docs/src/en/directives/on.md index 7ccf7a0ec..dd5140268 100644 --- a/packages/docs/src/en/directives/on.md +++ b/packages/docs/src/en/directives/on.md @@ -343,6 +343,15 @@ If you are listening for touch events, it's important to add `.passive` to your [→ Read more about passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners) + +### .passive.false + +In modern browsers, `wheel` and `touchmove` event listeners are passive by default. Pass `.passive.false` to make these events cancelable, so that you can call `preventDefault` on them. + +```alpine +
...
+``` + ### .capture Add this modifier if you want to execute this listener in the event's capturing phase, e.g. before the event bubbles from the target element up the DOM. diff --git a/tests/cypress/integration/directives/x-on.spec.js b/tests/cypress/integration/directives/x-on.spec.js index 47d598ec1..5d06e89a6 100644 --- a/tests/cypress/integration/directives/x-on.spec.js +++ b/tests/cypress/integration/directives/x-on.spec.js @@ -79,6 +79,23 @@ test('.passive modifier should disable e.preventDefault()', } ) +test('.passive.false modifier should enable e.preventDefault()', + html` +
+
+
+ `, + ({ get }) => { + get('div').trigger('touchmove') + get('div').should(haveData('defaultPrevented', true)) + } +) + test('.stop modifier', html`