---
title: Programmatic Listeners | Tutorial
contributors:
  - adamdbradley
  - saisrikardumpeti
  - manucorporat
  - mhevery
  - neonpie
  - mrhoodz
updated_at: '2023-06-25T19:43:33Z'
created_at: '2022-08-02T12:07:45Z'
---

There are times when your app needs to add a conditional listener. Sometimes a listener name is unknown, or you need to use an imperative approach to set up a listener.

Qwik provides the following [functions](https://qwik.dev/docs/core/events/#useonwindowdocument-hook) to attach a listener:

| Function          | Description                                               |
| ----------------- | --------------------------------------------------------- |
| `useOn()`         | Listen to events on the current component's root element. |
| `useOnDocument()` | Listen to events on the `document` object.                |
| `useOnWindow()`   | Listen to events on the `window` object.                  |

> **Your task**: Set up a click listener on the component to call `alert('Hello world!')`.

## Understanding the `$`

The `$` function signals Qwik to lazy load a reference. When setting up a listener with `useOn`, the second argument is a [Qwik URL](../../../docs/(qwik)/advanced/qrl/index.mdx).

Qwik URLs (QRL) are lazy-loadable references to your code. If `useOn` took a function directly rather than QRL, it would have to eagerly execute to allocate the listener closure. By using a QRL via the `$` function, Qwik can lazy load the closure only as `click` listener is triggered.

All three `useOn*()` hooks also accept an optional third argument for listener modifiers. For example:

- `{ passive: true }` for passive listeners.
- `{ capture: true }` to run in the capture phase.
- `{ preventdefault: true }` to call `event.preventDefault()` before the handler.
- `{ stoppropagation: true }` to call `event.stopPropagation()` before the handler.
