removeNode

Remove a node and schedule cleanup of its bindings.

removeNodeCleanup and Unbind

Remove a node and schedule cleanup of its bindings.

Overview

The removeNode function in Regor is responsible for removing a DOM node and initiating the unbinding process to clean up associated data bindings and event listeners. This function ensures that elements are safely removed from the DOM while also releasing any resources associated with them.

Try it live

Own a node through its full lifetimeLive API

Source value: 0 · Node: absent

0Source observers
0Root unbinders
0Custom cleanup calls

Unbind keeps the node but freezes its bindings. Remove + drain removes it and flushes deferred cleanup.

import {
  addUnbinder,
  createApp,
  drainUnbind,
  getBindData,
  html,
  observerCount,
  onUnmounted,
  ref,
  removeNode,
  sref,
  unbind,
  useScope,
} from 'regor'

export function createCleanup(interactive = false) {
  const host = sref<HTMLElement | null>(null)
  const source = ref(0),
    value = ref(0),
    present = ref(false),
    bound = ref(false)
  const observers = ref(0),
    callbacks = ref(0),
    registered = ref(0)
  let node: HTMLElement | null = null
  const inspect = () => {
    observers(observerCount(source))
    registered(node ? getBindData(node).unbinders.length : 0)
  }
  const mount = () => {
    if (!host() || node) return
    node = document.createElement('div')
    node.className = 'directive-card api-owned-node'
    host()!.appendChild(node)
    createApp(
      useScope(() => ({ source })),
      {
        element: node,
        template:
          '<strong>Owned node</strong><p>Bound value: <output r-text="source"></output></p>',
      },
    )
    addUnbinder(node, () => callbacks(callbacks() + 1))
    present(true)
    bound(true)
    inspect()
  }
  const detach = () => {
    if (node) unbind(node)
    bound(false)
    inspect()
  }
  const remove = async () => {
    if (!node) return
    removeNode(node)
    await drainUnbind()
    node = null
    present(false)
    bound(false)
    inspect()
  }
  onUnmounted(() => {
    if (node) {
      unbind(node)
      node.remove()
    }
  })
  return {
    interactive,
    host,
    value,
    present,
    bound,
    observers,
    callbacks,
    registered,
    mount,
    detach,
    remove,
    increment: () => {
      source(source() + 1)
      value(source())
      inspect()
    },
  }
}

export const cleanupTemplate = html` <div class="guide-demo">
  <div class="guide-session-bar">
    <button type="button" @click="mount" :disabled="!interactive || present">
      Mount node</button
    ><button type="button" @click="increment" :disabled="!interactive">
      Write +1</button
    ><button type="button" @click="detach" :disabled="!interactive || !bound">
      Unbind</button
    ><button type="button" @click="remove" :disabled="!interactive || !present">
      Remove + drain
    </button>
  </div>
  <p>
    Source value: <strong>{{ value }}</strong> · Node: {{ present ? 'present' :
    'absent' }}
  </p>
  <div :ref="host"></div>
  <div class="guide-metrics">
    <div><output>{{ observers }}</output><span>Source observers</span></div>
    <div><output>{{ registered }}</output><span>Root unbinders</span></div>
    <div><output>{{ callbacks }}</output><span>Custom cleanup calls</span></div>
  </div>
  <p class="guide-hint">
    Unbind keeps the node but freezes its bindings. Remove + drain removes it
    and flushes deferred cleanup.
  </p>
</div>`
import { createApp, RegorConfig, useScope } from 'regor'
import { apiExamples } from './examples'

const element = document.getElementById('api-demo')
const name = element?.dataset.example
if (element && name && Object.hasOwn(apiExamples, name)) {
  const example = apiExamples[name as keyof typeof apiExamples]
  const scope = useScope<object>(() => example.create(true))
  const config =
    'config' in scope.context && scope.context.config instanceof RegorConfig
      ? scope.context.config
      : undefined
  createApp(scope, { element, template: example.template }, config)
}

Mount, write, unbind, or remove and drain. Watch the DOM, observer count, and registered cleanup.

Usage

Removing a DOM Node and Unbinding

The removeNode function takes a single parameter:

  • node: The DOM node you want to remove from the document. This function will also initiate the unbinding process to clean up associated data bindings and event listeners.

Example

import { removeNode } from 'regor'

// Remove a DOM node and clean up associated data bindings and event listeners
const someElement = document.getElementById('example')
removeNode(someElement)

Parameters

  • node: The DOM node you want to remove from the document. This function will also initiate the unbinding process to clean up associated data bindings and event listeners.
Removal and cleanup have different timing

removeNode detaches the node immediately and queues unbinding. drainUnbind flushes the deferred work when you need deterministic cleanup.

Notes

  • The removeNode function is used to safely remove a DOM node from the document while ensuring that any bound data and associated logic are properly unbound and cleaned up.

  • When called on a specific DOM node, the function also initiates the unbinding process, which includes removing event listeners and cleaning up data bindings associated with the node and its descendants.

  • This function is typically used internally within Regor to facilitate the cleanup process when components are unmounted or when elements are removed from the DOM as part of Regor's rendering and lifecycle management.

  • It is essential to use the removeNode function or Regor's lifecycle management mechanisms when removing elements from the DOM to prevent memory leaks and ensure proper cleanup.

See Also

Related APIs and guides Continue with the references connected to removeNode.

Back to the API list