Skip to content

Instantly share code, notes, and snippets.

@lbgm
Last active March 7, 2023 17:05
Show Gist options
  • Save lbgm/9dd4e2473ca171d5216b53600925a47f to your computer and use it in GitHub Desktop.
Save lbgm/9dd4e2473ca171d5216b53600925a47f to your computer and use it in GitHub Desktop.
Input HTML Element Typing events handler for "Vue 3", get callback for typing finished and running
/**
* custom typing directive
* pass a function to this Directive, change inputInterval value to increase or decrease reactivity
*/
import type { DirectiveBinding, VNode, VueElement } from "vue";
export const typing = {
beforeMount(el: HTMLInputElement | VueElement, binding: DirectiveBinding, vnode: VNode) {
void vnode;
let inputTimer: number;
const inputInterval = binding.value.timing || 300;
for (const evt of ["keydown", "keyup"] ) {
(el as HTMLInputElement).addEventListener(evt, (event: Event) => {
if (event.type === "keyup") {
if (
(event as KeyboardEvent).key !== "Backspace" &&
typeof binding.value.run === "function"
)
binding.value.run(event); // is typing running callback
else if (binding.value.allowBackspace === true) binding.value.run(event); // is typing running callback
//
clearTimeout(inputTimer);
inputTimer = setTimeout(() => {
if (typeof binding.value.finish === "function")
binding.value.finish(event);
}, inputInterval); // when typing finished
} else if (event.type === "keydown") {
clearTimeout(inputTimer);
}
return null;
});
}
},
};
// add global directive
app.directive('typing', typing);
// use it like that
<input
v-typing="{
finish: (event) => {
$emit('typing:finished', event.target.value);
},
run: (event) => {
$emit('typing:running', event.target.value);
},
}"
type="text"
>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment