#svelte #javascript #frontend

Day 4: Events & Modifiers

Welcome to Day 4. Static pages are boring. Let’s make them interactive.

Modern Event Handling

In Svelte 5, we prefer standard HTML attributes over the on: directive.

  • Old (Svelte 3/4): on:click={handleClick}
  • New (Svelte 5): onclick={handleClick}

Why? It’s closer to the DOM standard, better for TypeScript, and faster.

<script lang="ts">
  function greet(event: MouseEvent) {
    alert("Hello!");
  }
</script>

<button onclick={greet}>
  Say Hello
</button>

Modifiers

In older Svelte, we had on:click|preventDefault. Now, we do it inside the handler, just like Vanilla JS.

<script lang="ts">
  function submit(e: Event) {
    e.preventDefault();
    console.log("Form submitted!");
  }
</script>

<form onsubmit={submit}>
  <input type="text" />
  <button>Save</button>
</form>

However, Svelte 5 creates a preventDefault wrapper helper if you really miss the syntax, but explicit control is preferred.

Inline Handlers

<button onclick={() => alert("Inline!")}>
  Click Me
</button>

Challenge for Day 4

  1. Create a <div> with specific dimensions (e.g., 200x200) and a background color.
  2. Track the mouse coordinates (offsetX, offsetY) when moving over it (onmousemove).
  3. Display the coordinates inside the div.
  4. Adding a button inside the div. Make sure clicking the button DOES NOT trigger anything on the div (hint: e.stopPropagation()).

Solution:

<script lang="ts">
  let x = $state(0);
  let y = $state(0);

  function handleMove(e: MouseEvent) {
    x = e.offsetX;
    y = e.offsetY;
  }

  function handleButton(e: MouseEvent) {
    e.stopPropagation();
    alert('Button clicked safely!');
  }
</script>

<!-- svelte-ignore a11y_no_static_element_interactions -->
<div 
  onmousemove={handleMove}
  style="width: 300px; height: 300px; background: #eee; padding: 20px;"
>
  <p>Mouse at: {x}, {y}</p>
  
  <button onclick={handleButton}>
    Don't bubble
  </button>
</div>

Interaction accomplished! Tomorrow we look at the magic of Two-Way Binding.