Skip to content

Commit

Permalink
add option to call preventDefault on all debounced events
Browse files Browse the repository at this point in the history
  • Loading branch information
nruffing committed Jan 7, 2024
1 parent 3652db6 commit 690a7db
Show file tree
Hide file tree
Showing 6 changed files with 29 additions and 2 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ function listener(event: Event) {
| `options` | `boolean`, `AddEventListenerOptions` or `undefined` | Optional. This is the same type as the browser API [`addEventListener.options` parameter](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#options). |
| `debounceMs` | `number` or `undefined` | Optionally specify a debounce timeout. |
| `debounceMode` | [`DebounceMode`](#debounce-mode) | Specify the type of desired debounce behavior. Defaults to `Timeout`. |
| `preventDefaultAllDebouncedEvents` | `boolean` or `undefined` | Optionally specify to call `preventDefault` on all events including ones that are debounced. For example. to ensure that the drop event always fires as expected, you should always include a `preventDefault` call in the part of your code which handles the dragover event. |
| `disabled` | `boolean` or `undefined` | Optionally disable/remove the event handler. |

### Composable
Expand Down Expand Up @@ -135,6 +136,7 @@ onBeforeUnmount(() => {
| `debounceMs` | `number` or `undefined` | Optionally specify a debounce timeout. |
| `debounceMode` | [`DebounceMode`](#debounce-mode) | Specify the type of desired debounce behavior. Defaults to `Timeout`. |
| `replaceExisting` | `boolean` or `undefined` | Optionally specify to replace any existing event handler that was attached using `native-event-vue`. Otherwise the new event listener will not be attached. |
| `preventDefaultAllDebouncedEvents` | `boolean` or `undefined` | Optionally specify to call `preventDefault` on all events including ones that are debounced. For example. to ensure that the drop event always fires as expected, you should always include a `preventDefault` call in the part of your code which handles the dragover event. |

### Debounce Mode

Expand All @@ -148,6 +150,9 @@ The following debounce behavior modes are available via the `DebounceMode` enum.

## Release Notes

### v1.4.0
* Add option to call `preventDefault` on all events including ones that are debounced. For example. to ensure that the drop event always fires as expected, you should always include a `preventDefault` call in the part of your code which handles the dragover event. |

### v1.3.0
* Add TS support for attaching events to the window object when using `useNativeEvent`.

Expand Down
1 change: 1 addition & 0 deletions cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"cstat",
"datagridvue",
"docsearch",
"dragover",
"fstat",
"gapi",
"keyline",
Expand Down
10 changes: 10 additions & 0 deletions lib/composables/useDebounce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export function useDebounce(
func: FunctionToDebounce | EventListenerObject,
timeoutMs: number,
mode: DebounceMode = DebounceMode.Timeout,
preventDefaultAllEvents?: boolean,
): DebouncedFunction {
const ensure = useEnsure('useDebounce')
ensure.ensureExists(func, 'func')
Expand Down Expand Up @@ -67,6 +68,15 @@ export function useDebounce(
return
}

/**
* For example, to ensure that the drop event always fires as expected, you should always include a preventDefault() call in the part of your
* code which handles the dragover event.
* https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/drop_event
*/
if (preventDefaultAllEvents && args?.length > 0 && args[0] instanceof Event) {
args[0].preventDefault()
}

if (immediate) {
/**
* If this is the first call, execute immediately
Expand Down
5 changes: 4 additions & 1 deletion lib/composables/useNativeEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export type NativeEvent = { destroy: () => void } | undefined
* @param debounceMs Optionally specify a debounce timeout.
* @param debounceMode Specify the type of desired debounce behavior. Defaults to `Timeout`.
* @param replaceExisting Optionally specify to replace any existing event handler that was attached using `native-event-vue`. Otherwise the new event listener will not be attached.
* @param preventDefaultAllDebouncedEvents Optionally specify to call `preventDefault` on all events including ones that are debounced. For example. to ensure that the drop event always fires as
* expected, you should always include a `preventDefault` call in the part of your code which handles the dragover event.
* @returns {@link NativeEvent} object with a destroy method to remove the event listener.
*/
export function useNativeEvent(
Expand All @@ -26,6 +28,7 @@ export function useNativeEvent(
debounceMs?: number,
debounceMode?: DebounceMode,
replaceExisting?: boolean,
preventDefaultAllDebouncedEvents?: boolean,
): NativeEvent {
const ensure = useEnsure('useNativeEvent')
ensure.ensureExists(domEl, 'domEl')
Expand Down Expand Up @@ -63,7 +66,7 @@ export function useNativeEvent(
}

if (debounceMs) {
const debounced = useDebounce(listener, debounceMs, debounceMode)
const debounced = useDebounce(listener, debounceMs, debounceMode, preventDefaultAllDebouncedEvents)
listenerRef.value = debounced
log('useNativeEvent | event listener debounced', { domEl, event, options, debounceMs, debounceMode, replaceExisting })
}
Expand Down
6 changes: 6 additions & 0 deletions lib/directives/nativeEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ export interface NativeEventOptions {
* Specify the type of desired debounce behavior. Defaults to `Timeout`.
*/
debounceMode?: DebounceMode
/**
* Optionally specify to call `preventDefault` on all events including ones that are debounced. For example. to ensure that the drop event always fires as
* expected, you should always include a `preventDefault` call in the part of your code which handles the dragover event.
*/
preventDefaultAllDebouncedEvents?: boolean | undefined
/**
* Optionally disable/remove the event handler.
*/
Expand Down Expand Up @@ -78,6 +83,7 @@ function addEventListener(domEl: HTMLElement, binding: DirectiveBinding<NativeEv
binding.value.debounceMs,
binding.value.debounceMode,
replaceExisting,
binding.value.preventDefaultAllDebouncedEvents ?? false,
)
//log('native-event | event listener added', { domEl, binding: binding.value, replaceExisting })
}
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "native-event-vue",
"version": "1.3.0",
"version": "1.4.0",
"type": "module",
"private": false,
"description": "Directives and composables for wiring up and debouncing native HTML events in Vue.",
Expand All @@ -20,6 +20,8 @@
"keywords": [
"html event",
"native event",
"dom event",
"browser event",
"event",
"vuejs",
"vue",
Expand Down

0 comments on commit 690a7db

Please sign in to comment.