Обработка событий DOM

События DOM в Svelte 5 — это обычные атрибуты onclick, oninput, onsubmit, принимающие функции.

Svelte 5 убрал особый синтаксис событий: теперь onclick — это просто атрибут, как в обычном HTML, только со значением-функцией.

Интерфейс без обработки событий мёртв. В Svelte 5 события элементов вешаются через атрибуты on*: onclick, oninput, onsubmit, onkeydown и так далее. Значение атрибута — функция-обработчик. Это намеренно близко к нативному HTML и JavaScript, чтобы не приходилось учить отдельный синтаксис (в Svelte 4 было on:click с двоеточием — теперь без него).

Внутри обработчика вы получаете стандартный объект события, можете вызвать preventDefault() или stopPropagation(), прочитать event.target.value и менять реактивное состояние. Так как обработчик — обычная функция, в нём доступно всё из скрипта компонента.

<script>
  let text = $state('');
  let submitted = $state('');

  function onSubmit(event) {
    event.preventDefault();   // не перезагружать страницу
    submitted = text;
  }
</script>

<form onsubmit={onSubmit}>
  <input value={text} oninput={(e) => text = e.target.value} />
  <button>Отправить</button>
</form>
<p>Отправлено: {submitted}</p>

Для полей ввода вместо ручного oninput чаще используют bind:value, который двусторонне связывает значение с состоянием (об этом подробнее в уроке про связывание). Но важно понимать базовый механизм: событие → функция → изменение состояния → обновление интерфейса.

Как это работает под капотом

Компилятор навешивает ваш обработчик через addEventListener на нужный элемент и снимает его при удалении элемента. Делегирование части событий Svelte оптимизирует автоматически. Смоделируем цикл «событие → состояние → рендер» на чистом JS.

// Цикл: событие -> изменение состояния -> перерисовка
let state = { text: '' };
function render() { console.log('UI показывает:', state.text || '(пусто)'); }

function oninput(value) {  // имитируем e.target.value
  state.text = value;      // меняем состояние
  render();                // Svelte сделал бы это автоматически
}

render();          // UI показывает: (пусто)
oninput('При');    // UI показывает: При
oninput('Привет'); // UI показывает: Привет

Попробуй сам ▶ — вставь код в консоль браузера (F12 → Console) и нажми Enter, чтобы увидеть вывод.

  пользователь печатает / кликает
        |
        v
  oninput / onclick (функция-обработчик)
        |
        v
  изменение $state
        |
        v
  Svelte точечно обновляет DOM

Частые ошибки

  • Использовать старый синтаксис on:click. В Svelte 5 это просто onclick.
  • Забыть event.preventDefault() в onsubmit. Иначе страница перезагрузится.
  • Вызывать обработчик сразу: onclick={handle()}. Нужно передавать ссылку: onclick={handle}.

Best practices

  • Передавайте функцию, а не её вызов; для аргументов используйте стрелку: onclick={() => act(id)}.
  • Для полей ввода предпочитайте bind:value ручному oninput.
  • Выносите сложные обработчики в именованные функции — разметка остаётся читаемой.

Замыкания и передача аргументов

Одна тонкость регулярно сбивает новичков: как передать в обработчик дополнительный аргумент. Если вы напишете onclick={remove(id)}, функция выполнится сразу при рендере, а не по клику, потому что скобки означают вызов. Правильный приём — обернуть вызов в стрелочную функцию: onclick={() => remove(id)}. Теперь по клику выполнится именно стрелка, которая внутри себя вызовет remove с нужным аргументом. Это особенно частый паттерн в циклах, где каждой строке нужен свой идентификатор. Благодаря замыканиям стрелка «запоминает» id своей итерации. Понимание этой механики избавляет от двух типичных багов сразу: преждевременного вызова обработчика и потери аргумента. И помните общий принцип цикла событий в Svelte: обработчик меняет реактивное состояние, а перерисовку зависимого DOM движок берёт на себя — вам не нужно ни искать узлы, ни трогать их вручную.

Итог: события в Svelte 5 — это атрибуты on* с функциями-обработчиками. Обработчик меняет состояние, а Svelte точечно перерисовывает зависимый DOM.

Проверьте себя
1. Как в Svelte 5 навешивается обработчик клика?
Aon:click={handle}
Bonclick={handle}
C@click="handle"
Dv-on:click=handle
2. В чём ошибка записи onclick={handle()}?
AНи в чём, это корректно
Bhandle вызовется сразу при рендере, а не по клику — нужно передать ссылку handle
CНельзя использовать функции в обработчиках
Donclick не существует