How LiveView JS commands persists through renders?
Phoenix LiveView provides a declarative API to describe some limited JavaScript
to be executed in the browser in order to avoid server round-trips for
absolutely everything. One common use case it updating HTML data- attributes,
which in turn drives CSS selectors.
The example below renders a button which on click, changes background color to green:
<button
style="background-color: attr(data-color type(<color>))"
phx-click={JS.toggle_attribute({"data-color", "green", "pink"})}
>
toggle
</button>
Notice the modern CSS function
attr()which returns an attribute value and uses it in a CSS property.
The server knows only how to encode the JS command into the HTML element
phx-click attribute:
[["toggle_attr",{"attr":["data-color","green","pink"]}]]
The JavaScript part of LiveView wires the "click" event handlers, parses the
JS command string, and carries out it's instructions. In this case, toggling the
data-color attribute.
But if the DOM changes completely out of knowledge from the server, do those changes survive after the server re-renders?
Demo time
The changes performed purely in the client, through JS commands, survive re-renders. Thanks to smart DOM patching which accounts for sticky operations.
The demo below shows a div which the background color is dictated by the
data-color attribute. It's initial value is rendered as the @color assign.
Notice that:
- Initially,
push_eventupdates both the@colorassign anddata-colorattr. set_attributeupdates onlydata-color, and in consequence the styles too.- After
set_attributeruns once,push_eventwon't updatedata-coloranymore.
Sticky DOM operations
LiveView does all the HTML rendering in the server, sending the smallest diffs possible to the client when the page must be updated. In the client, it uses the morphdom library to patch the current DOM tree with the diffs.
Morphdom provides the onBeforeElUpdated(fromEl, toEL) callback to
DOM.applyStickyOperations src