苗条的长按
Svelte Long Press
我需要一个长按事件来绑定到 svelte 3 中的按钮。我想以尽可能少的 "boilerplaty" 方式做到这一点。
我试过使用长按功能,但这似乎有点复杂和老套,而且似乎也有点慢。
function longPress(node, callback) {
console.log(node)
function onmousedown(event) {
const timeout = setTimeout(() => callback(node.innerHTML), 1000);
function cancel() {
clearTimeout(timeout);
node.removeEventListener("mouseup", cancel, false);
}
node.addEventListener("mouseup", cancel, false);
}
node.addEventListener("mousedown", onmousedown, false);
return {
destroy() {
node.removeEventListener("mousedown", onmousedown, false);
}
};
}
</script>
<div>
<Video />
{#each Object.entries(bindings) as [id, value]}
<button on:click = {()=>longPress(this,addImage)}> {id} </button>
{/each}
</div>
这行得通,但我相信还有更好的方法。
对于这种事情,我会使用 action,这是一个在创建元素时 运行s 的函数(并且可以 return当参数更改或元素被销毁时 运行 的函数):https://svelte.dev/tutorial/actions
在这种情况下,您可以创建一个可重复使用的 longpress
操作,就像上面的函数一样,它会在目标元素上分派一个自定义 longpress
事件,您可以像本地 DOM 事件:
<script>
import { longpress } from './actions.js';
let pressed;
</script>
<button use:longpress on:longpress="{e => pressed = true}">
longpress me
</button>
export function longpress(node, threshold = 500) {
// note — a complete answer would also consider touch events
const handle_mousedown = () => {
let start = Date.now();
const timeout = setTimeout(() => {
node.dispatchEvent(new CustomEvent('longpress'));
}, threshold);
const cancel = () => {
clearTimeout(timeout);
node.removeEventListener('mousemove', cancel);
node.removeEventListener('mouseup', cancel);
};
node.addEventListener('mousemove', cancel);
node.addEventListener('mouseup', cancel);
}
node.addEventListener('mousedown', handle_mousedown);
return {
destroy() {
node.removeEventListener('mousedown', handle_mousedown);
}
};
}
这种方法的优点是你已经将 'longpress' 的定义与处理它的东西分开了,所以 addImage
/node.innerHTML
逻辑可以完全分开,并且您可以 re-use 在您应用的其他地方执行该操作。
完整演示,包括将参数传递给操作:https://svelte.dev/repl/f34b6159667247e6b6abb5142b276483?version=3.6.3
我需要一个长按事件来绑定到 svelte 3 中的按钮。我想以尽可能少的 "boilerplaty" 方式做到这一点。
我试过使用长按功能,但这似乎有点复杂和老套,而且似乎也有点慢。
function longPress(node, callback) {
console.log(node)
function onmousedown(event) {
const timeout = setTimeout(() => callback(node.innerHTML), 1000);
function cancel() {
clearTimeout(timeout);
node.removeEventListener("mouseup", cancel, false);
}
node.addEventListener("mouseup", cancel, false);
}
node.addEventListener("mousedown", onmousedown, false);
return {
destroy() {
node.removeEventListener("mousedown", onmousedown, false);
}
};
}
</script>
<div>
<Video />
{#each Object.entries(bindings) as [id, value]}
<button on:click = {()=>longPress(this,addImage)}> {id} </button>
{/each}
</div>
这行得通,但我相信还有更好的方法。
对于这种事情,我会使用 action,这是一个在创建元素时 运行s 的函数(并且可以 return当参数更改或元素被销毁时 运行 的函数):https://svelte.dev/tutorial/actions
在这种情况下,您可以创建一个可重复使用的 longpress
操作,就像上面的函数一样,它会在目标元素上分派一个自定义 longpress
事件,您可以像本地 DOM 事件:
<script>
import { longpress } from './actions.js';
let pressed;
</script>
<button use:longpress on:longpress="{e => pressed = true}">
longpress me
</button>
export function longpress(node, threshold = 500) {
// note — a complete answer would also consider touch events
const handle_mousedown = () => {
let start = Date.now();
const timeout = setTimeout(() => {
node.dispatchEvent(new CustomEvent('longpress'));
}, threshold);
const cancel = () => {
clearTimeout(timeout);
node.removeEventListener('mousemove', cancel);
node.removeEventListener('mouseup', cancel);
};
node.addEventListener('mousemove', cancel);
node.addEventListener('mouseup', cancel);
}
node.addEventListener('mousedown', handle_mousedown);
return {
destroy() {
node.removeEventListener('mousedown', handle_mousedown);
}
};
}
这种方法的优点是你已经将 'longpress' 的定义与处理它的东西分开了,所以 addImage
/node.innerHTML
逻辑可以完全分开,并且您可以 re-use 在您应用的其他地方执行该操作。
完整演示,包括将参数传递给操作:https://svelte.dev/repl/f34b6159667247e6b6abb5142b276483?version=3.6.3