UNPKG

3.73 kBMarkdownView Raw
1# Events
2
3Marko’s event API supports:
4
5- [Browser events](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Events) on native tags
6- Custom events from [custom tags](./custom-tags.md)
7
8Note that **you can’t mix event targets and event types**: custom tags can only listen for custom events, and native tags can only listen for native events.
9
10## Listening to events
11
12Both kinds of events are received with an `on-*` attribute and the [attribute arguments syntax](./syntax.md#arguments):
13
14```marko
15<input type="checkbox"
16 on-change=(event => console.info(`Checked? ${event.target.checked}`))
17/>
18```
19
20The [first argument for the attribute can be a function](#function-handler), or [a string matching a method name](#method-handler) on the [component’s `class` declaration](./class-components.md).
21
22### Function handler
23
24If you provide a function as the first argument of the `on-*` attribute, the function is called whenever the event fires, like standard event listeners.
25
26Below we use the [`static` prefix](./syntax.md#static-javascript) to define a function, then use it as a `click` handler:
27
28```marko
29static function handleClick(event) {
30 event.preventDefault();
31 console.log("Clicked!");
32}
33
34<button on-click(handleClick)>
35 Log click
36</button>
37```
38
39In the above example, any time the `<button>` is clicked the `handleClick` function is called.
40
41You can also use an inline arrow function:
42
43```marko
44<button on-click(() => alert("Clicked! 🎉"))>
45 Celebrate click
46</button>
47```
48
49…or anything that evaluates to a function:
50
51```marko
52const handler = input.dontBreakMyApp ?
53 () => console.error("Clicked!") :
54 () => { throw Error("Clicked!") }
55
56<button on-click(handler)>
57 Do not click
58</button>
59```
60
61### Method handler
62
63When a string is the first argument, Marko calls a matching method on the component's `class`.
64
65```marko
66class {
67 logChange(newTab) {
68 console.log(`changed to: ${newTab}`);
69 }
70}
71
72<my-tabs on-switch-tab("logChange")>
73
74</my-tabs>
75```
76
77When `<my-tabs>` emits the `switch-tab` event, it will call its `logChange` method.
78
79Within the handler you can access the current component instance, read data, emit events, update state, etc.
80
81### Binding additional arguments
82
83Arguments after the handler are prepended when the handler is called:
84
85```marko
86static function removeFriend(friendId, event) {
87 event.preventDefault();
88 window.myAPI.unfriend(friendId);
89}
90
91<for|friend| of=input.friends>
92 <button on-click(removeFriend, friend.id)>
93 Unfriend ${friend.name}
94 </button>
95</for>
96```
97
98Here we share the logic for `removeFriend()` with each `friend` in the `friends` array. When the `<button>` is clicked, the `id` of the removed `friend` is passed to the `removeFriend()`, handler followed by the DOM `click` event.
99
100## Emitting custom events
101
102The recommended way for a [custom tag](./custom-tags.md) to communicate with its parent is through **custom events**.
103
104All components implement a [Node.js-style event emitter](https://nodejs.org/api/events.html#events_class_eventemitter) to send events to parent components.
105
106_email-input.marko_
107
108```marko
109class {
110 handleChange(event) {
111 if (event.target.validity.valid) {
112 // Only emit email-changes if they are valid.
113 this.emit("email-change", { email: event.target.value });
114 }
115 }
116}
117
118<input type="email" name=input.name on-change("handleChange")/>
119```
120
121The above code listens to native `change` events from the `<input>` element, and then emits its own `email-change` event if the change was valid.
122
123```marko
124<form>
125 <email-input name="email" on-email-change(...)/>
126</form>
127```
128
129> **Note:** Events are not received as `input`; you cannot access `input.onEmailChange`. Instead, they set up subscriptions.