How to Access Real DOM Nodes with Mercury/Virtual-DOM, Part 2
In the time since my first post on accessing non-virtual DOM nodes with Mercury / virtual-dom, I’ve learnt that my approach wasn’t as sound as I initially thought. The creator of Mercury, Jake Verbaten, let me know that virtual-dom hooks should only modify node attributes, otherwise the behaviour will be undefined ("innerHTML in hooks breaks the tree indexing that virtual-dom is using").
Instead, I learnt, one should use Mercury Widgets to render directly to the DOM. These aren’t subject to the same restrictions, so it turns out I should’ve been writing widgets instead of hooks.
Armed with this new knowledge, I wrote an example on accessing the non-virtual (real) DOM with either hooks (for manipulating node attributes) or widgets (for rendering new nodes), which was integrated into the Mercury project as real-dom.js. I’ve posted an extract of the example below, which shows only how to render a DOM node in a Widget:
'use strict';
var hg = require('mercury');
function Widget() {
// This is required for an instance to be recognized by Mercury as a widget
this.type = 'Widget';
}
Widget.prototype.init = function init() {
var elem = document.createElement('div');
elem.innerHTML = 'Content set directly on real DOM node, by widget ' +
'<em>before</em> update.';
return elem;
};
Widget.prototype.update = function update(prev, elem) {
elem.innerHTML = 'Content set directly on real DOM node, by widget ' +
'<em>after</em> update.';
};
function App() {
var state = hg.state({
updated: hg.value(false)
});
setTimeout(function timer() {
state.updated.set(true);
}, 2000);
return state;
}
App.render = function App(state) {
// Create widget controlled node
return new Widget();
};
hg.app(document.body, App(), App.render);