Для такого рода вещей я бы использовал действие , которое является функцией, которая запускается при создании элемента (и может возвращать функции, которые запускаются при изменении параметров или уничтожении элемента): https://svelte.dev/tutorial/actions
В этом случае вы можете создать повторно используемое действие longpress
, очень похожее на вашу функцию выше, которое отправляет пользовательское событие longpress
на целевой элемент, который вы можете прослушивать, как собственный DOMevent:
<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
может бытьчисто разделены, и вы можете повторно использовать действие в другом месте в вашем приложении.
Полная демонстрация, включая передачу параметра в действие: https://svelte.dev/repl/f34b6159667247e6b6abb5142b276483?version=3.6.3