# lu-on
`lu-on` is used to attach event listeners to elements. It supports both inline expressions and method calls from your scope.
## Shorthand
The `@` character is a shorthand for `lu-on`.
```html
```
## Event Handlers
### Inline Handlers
You can write JavaScript expressions directly in the `@` directive.
```html
```
### Method Handlers
If the logic is complex, use a method on the scope. Template object literals hold data only — they
cannot declare methods — so return the method from a factory and hand the factory to the app:
```html
```
## Accessing the Original Event
If you need the original DOM event object in an inline handler, you can pass the special `$event` variable.
```html
```
If using a method handler, the event is automatically passed as the first argument if no arguments are provided in the template.
```html
```
## Event Modifiers
Lune provides modifiers to simplify common event handling tasks. Modifiers are postfixed with a dot.
- `.stop`: Calls `event.stopPropagation()`
- `.prevent`: Calls `event.preventDefault()`
- `.self`: Only triggers the handler if the event was dispatched from the element itself (not a child)
- `.once`: The handler will be triggered at most once
- `.capture`: Adds the listener in capture mode
- `.passive`: Adds the listener with `{ passive: true }`
- `.exact`: Only triggers if no additional system modifier keys are pressed
`.once`, `.capture`, and `.passive` are forwarded to `addEventListener` as listener options; the rest are checked when the event fires.
```html
```
### Keyboard Modifiers
You can use any valid key name (in kebab-case) as a modifier for keyboard events.
```html
```
### System Modifier Keys
You can restrict handlers to specific keyboard modifier keys.
- `.ctrl`
- `.shift`
- `.alt`
- `.meta`
```html
```
### `.exact` Modifier
The `.exact` modifier ensures the event only triggers when exactly the specified modifier keys are pressed (no additional system keys).
```html
```
### Mouse Button Modifiers
Restrict handlers to specific mouse buttons.
- `.left`
- `.right`
- `.middle`
```html
```
On a `click` binding these two also swap the event being listened to: `.right` listens for `contextmenu`, and `.middle` listens for `mouseup`.
## Special Lifecycle Events
Lune emits special events when an element is mounted or unmounted. These **must** be prefixed with `lune:` — the bare `@mounted` / `@unmounted` names log a development error telling you to add the prefix.
- `@lune:mounted`: Fired when the element is mounted to the DOM.
- `@lune:unmounted`: Fired when the element is removed from the DOM.
```html
```
## Limitations
### Handlers Run Through the Expression Engine
Inline handlers are compiled by Lune's [expression engine](/advanced/security), not by `new Function()`. Everyday handler code is unaffected, but `window`, `document` and `fetch` are not reachable from the attribute, and `async`/`await` and loops are not part of the supported subset. Put that logic in a scope method and call it:
```html
```
### Object Syntax Not Supported
The `lu-on="eventHandlers"` object syntax (passing an object of event handlers) is **not** supported in Lune. You must use individual `@event` bindings:
```html
```