Home Features Docs Blog Examples FAQ
DJE-011 Error Template

innerHTML destroying event listeners

Error message

Event listeners stop working after LiveView re-render

Before the DOM morphing implementation, applyDjUpdateElements() used innerHTML to apply full HTML updates. This destroyed all event listeners that were bound to elements inside the updated region (e.g., DOMContentLoaded drag/drop handlers). Fixed in v0.3.0 with morphdom-style DOM diffing (morphChildren/morphElement).

bug-fixed dom events liveview

Affected versions: <0.3.0

Solutions

Recommended

Upgrade to djust >= 0.3.0 (DOM morphing)

djust 0.3.0 introduced DOM morphing that reuses existing DOM elements instead of replacing them with innerHTML. Event listeners are preserved across re-renders. Elements are matched by id (keyed) or tag+position (unkeyed).

Before (problematic)
// Old behavior in vdom-patch.js
function applyDjUpdateElements(target, newHtml) {
    target.innerHTML = newHtml;  // Destroys all event listeners!
}
After (fixed)
// New behavior with DOM morphing
function applyDjUpdateElements(target, newHtml) {
    const template = document.createElement("template");
    template.innerHTML = newHtml;
    morphChildren(target, template.content);
    // Event listeners on existing elements are preserved
}

Use dj-update="ignore" for manually managed regions

Mark elements that have manually-bound event listeners with dj-update="ignore" to prevent djust from updating them during re-renders.

Before (problematic)
<div id="drag-zone">
    <!-- Event listeners destroyed on every re-render -->
</div>
After (fixed)
<div id="drag-zone" dj-update="ignore">
    <!-- djust will skip this element during DOM patching -->
</div>