Svelte Long Press - PullRequest
       26

Svelte Long Press

0 голосов
/ 02 июля 2019

Мне нужно длинное нажатие, чтобы связать кнопки в svelte 3. Я хочу сделать это как можно менее «наглядно».

Я пробовал использовать функцию длинного нажатия, но это кажетсянемного запутанный и хакерский, также кажется немного медленным.

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>

Это работает, но я уверен, что есть лучший способ.

1 Ответ

5 голосов
/ 02 июля 2019

Для такого рода вещей я бы использовал действие , которое является функцией, которая запускается при создании элемента (и может возвращать функции, которые запускаются при изменении параметров или уничтожении элемента): 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

...