DOM events

As you’ll see in the following example, you can listen for any event on an element using the on: event name:

<div on:mousemove={handleMousemove}>
	The mouse position is {m.x} x {m.y}
</div>
Copy the code

Complete code:

<script>
	let m = { x: 0.y: 0 };

	function handleMousemove(event) {
		m.x = event.clientX;
		m.y = event.clientY;
	}
</script>

<div on:mousemove={handleMousemove}>
	The mouse position is {m.x} x {m.y}
</div>

<style>
	div { width: 100%; height: 100%; }
</style>
Copy the code

Inline processing

You can also declare event handlers inline:

<div on:mousemove="{e => m = { x: e.clientX, y: e.clientY }}">
	The mouse position is {m.x} x {m.y}
</div>
Copy the code

Quotes are optional, but in some environments they can help improve syntax prominence.

In some frameworks, you might see recommendations to avoid using inline event handlers for performance reasons, especially in loops. This advice does not apply to Svelte, the compiler will always do the right thing, no matter which form you choose.

Event modifier

DOM event handlers can use modifiers to change their behavior. For example, a handler with the once modifier runs only once:

<script>
	function handleClick() {
		alert('no more alerts')}</script>

<button on:click|once={handleClick}>
	Click me
</button>
Copy the code

A complete list of modifiers:

  • PreventDefault: before running the handler. For example, it is useful for client-side form processing.
  • StopPropagation: Prevents events from reaching the next element. The bubbling.
  • Passive: Improved scroll performance for touch/Scroll events (Svelte automatically adds scroll in a safe place)
  • Nonpassive: You can view the scrolling performance improved by using passive
  • Capture: Use event capture mode when adding event listeners, where events triggered by the element itself are processed before being passed on to internal elements for processing.
  • Once: responds only once
  • Self: Only whenevent.targetThe handler is fired when the current element is itself, that is, the event is not fired from an internal element.

You can multiple modifiers used at the same time, for example: on: click | once | the capture = {… }

Component events

Components can also distribute events. To do this, they must create an event dispatcher:

<script>
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	function sayHello() {
		dispatch('message', {
			text: 'Hello! '
		});
	}
</script>
Copy the code

CreateEventDispatcher must be called when the component is first instantiated. Cannot be used in subsequent functions, such as the setTimeout callback. This binds the event distribution to the component instance.

Note that, thanks to the on:message directive, the App component is listening for messages sent by the Inner component. This directive is a property prefixed on: followed by the name of the event we want to distribute (in this case message).

Complete code:

Inner.sevlte

<script>
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	function sayHello() {
		dispatch('message', {
			text: 'Hello! '
		});
	}
</script>

<button on:click={sayHello}>
	Click to say hello
</button>
Copy the code

App.sevlte

<script>
	import Inner from './Inner.svelte';

	function handleMessage(event) {
		alert(event.detail.text);
	}
</script>

<Inner on:message={handleMessage}/>
Copy the code

Without the on:message attribute, the message will still be sent, but the application will not respond to it. You can try removing the on: Message property and pressing the button again.

You can also try to change the event name to something else. For example, change dispatch (‘message’) to Dispatch (‘myevent’) in inner-.svelte, and change the property name from on: message to on: myevent in the app.svelte component.

Event forwarding

Unlike DOM events, component events do not bubble. If you want to listen for an event on a deeply nested component, the intermediate component must forward the event.

In this case, we have the same app.svelte and Inner. Svelte as before, but now we have an Outer. Svelte component containing < Inner />.

<script>
	import Inner from './Inner.svelte';
</script>

<Inner/>
Copy the code

One way we can solve this problem is to add createEventDispatcher to outt. svelte, listen for the message event, and create a handler for it:

<script>
	import Inner from './Inner.svelte';
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	function forward(event) {
		dispatch('message', event.detail);
	}
</script>

<Inner on:message={forward}/>
Copy the code

But there’s a lot of code to write, so Svelte gives us an equivalent shorthand: on:message means forward all message events.

<script>
	import Inner from './Inner.svelte';
</script>

<Inner on:message/>
Copy the code

Complete code:

Outer.sevlte

<script>
	import Inner from './Inner.svelte';
</script>

<Inner on:message/>
Copy the code

Inner.sevlte

<script>
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();

	function sayHello() {
		dispatch('message', {
			text: 'Hello! '
		});
	}
</script>

<button on:click={sayHello}>
	Click to say hello
</button>
Copy the code

App.sevlte

<script>
	import Outer from './Outer.svelte';

	function handleMessage(event) {
		alert(event.detail.text);
	}
</script>

<Outer on:message={handleMessage}/>
Copy the code

DOM Event Forwarding

Event forwarding also applies to DOM events.

CustomButton.svelte

<button>
	Click me
</button>

<style>
	button {
		background: #E2E8F0;
		color: #64748B;
		border: unset;
		border-radius: 6px;
		padding:.75rem 1.5 rem;
		cursor: pointer;
	}
	button:hover {
		background: #CBD5E1;
		color: # 475569;
	}
	button:focus {
		background: #94A3B8;
		color: #F1F5F9;
	}
</style>
Copy the code

App.sevlte

<script>
	import CustomButton from './CustomButton.svelte';

	function handleClick() {
		alert('Button Clicked');
	}
</script>

<CustomButton on:click={handleClick}/>
Copy the code

If we want to trigger the click event for the component
, we need to add the click event to

<button on:click>
	Click me
</button>
Copy the code

If you want to experience the charm of the event for yourself, you need to go to the official website to experience it for yourself. Sevlte event