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).
Affected versions: <0.3.0
Solutions
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).
// Old behavior in vdom-patch.js
function applyDjUpdateElements(target, newHtml) {
target.innerHTML = newHtml; // Destroys all event listeners!
}
// 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.
<div id="drag-zone">
<!-- Event listeners destroyed on every re-render -->
</div>
<div id="drag-zone" dj-update="ignore">
<!-- djust will skip this element during DOM patching -->
</div>