---
title: createEventListener
description: Attach typed DOM event listeners that clean up automatically when
  the Solid owner scope disposes.
package: moraine
version: 0.6.0
repository: https://github.com/subframe7536/moraine
---

# createEventListener

> Attach typed DOM event listeners that clean up automatically when the Solid owner scope disposes.

`createEventListener` and `createEventListenerMap` attach DOM event listeners to Window, Document, or HTML elements. They automatically register `onCleanup()` in the active SolidJS reactive scope to prevent memory leaks.

## Import

```tsx
import { createEventListener, createEventListenerMap } from 'moraine/utils'
```

## Signatures

```ts
function createEventListener<
  TTarget extends EventTarget,
  TType extends EventTypeForTarget<TTarget>,
>(
  target: TTarget | null | undefined,
  type: TType,
  listener: (event: EventMapForTarget<TTarget>[TType]) => void,
  options?: boolean | AddEventListenerOptions,
): void

function createEventListenerMap<TTarget extends EventTarget>(
  target: TTarget | null | undefined,
  listeners: EventListenerMap<TTarget>,
  options?: boolean | AddEventListenerOptions,
): void
```

## Usage Example

### Single Event with `createEventListener`

```tsx title="src/EscapeListener.tsx"
import { onMount } from 'solid-js'
import { createEventListener } from 'moraine/utils'

export function EscapeListener(props: { onEscape: () => void }) {
  onMount(() => {
    // Strongly typed: e is KeyboardEvent for window keydown.
    createEventListener(window, 'keydown', (e) => {
      if (e.key === 'Escape') {
        props.onEscape()
      }
    })
  })

  return null
}
```

### Multiple Events with `createEventListenerMap`

```tsx title="src/DragObserver.tsx"
import { onMount } from 'solid-js'
import { createEventListenerMap } from 'moraine/utils'

export function DragObserver() {
  onMount(() => {
    createEventListenerMap(window, {
      pointermove: (e) => console.log('Pointer at:', e.clientX, e.clientY),
      pointerup: () => console.log('Drag ended'),
      pointercancel: () => console.log('Drag cancelled'),
    })
  })

  return null
}
```

## Features

- **Type Inferred**: Event types automatically narrow according to the target (e.g. `window.resize` gives `UIEvent`, `document.keydown` gives `KeyboardEvent`).
- **Owner Scope Bound**: Cleanups are registered with `onCleanup` in the active Solid owner, including when called from `onMount`.
- **Safe Null Handling**: Passes `null` or `undefined` targets safely without runtime exceptions.

