This solution is generated by ChatGPT, correctness is not guaranteed.
AI solution for JavaScript Coding Question on BFE.dev
113. Virtual DOM I
Solution:
To solve this problem, we can define two functions virtualize
and render
. virtualize
function will take a real DOM tree and return an object literal that represents the same tree structure. The render
function will take this object literal presentation and recreate a DOM tree.
function virtualize(node) {
// Base case: if node is TextNode
if (node.nodeType === Node.TEXT_NODE) {
return node.textContent;
}
// Otherwise, create object for element node
const obj = {
type: node.nodeName.toLowerCase(),
props: {},
children: [],
};
// Add properties
for (const prop of node.attributes) {
obj.props[prop.name] = prop.value;
}
// Add children
for (const child of node.childNodes) {
obj.children.push(virtualize(child));
}
return obj;
}
function render(obj) {
// Base case: if obj is TextNode
if (typeof obj === "string") {
return document.createTextNode(obj);
}
// Create element node
const node = document.createElement(obj.type);
// Set properties
for (const prop in obj.props) {
node.setAttribute(prop, obj.props[prop]);
}
// Add children
for (const child of obj.children) {
node.appendChild(render(child));
}
return node;
}
Let's test our solution:
// Create real DOM tree
const root = document.createElement("div");
root.innerHTML = `
<h1> this is </h1>
<p class="paragraph">a <button>button</button> from <a href="https://bfe.dev"><b>BFE</b>.dev</a></p>
`;
// Virtualize DOM tree
const obj = virtualize(root);
console.log(obj);
/*
{
type: 'div',
props: {},
children: [
{
type: 'h1',
props: {},
children: [' this is ']
},
{
type: 'p',
props: { class: 'paragraph' },
children: [
'a ',
{
type: 'button',
props: {},
children: ['button']
},
' from ',
{
type: 'a',
props: { href: 'https://bfe.dev' },
children: [{ type: 'b', props: {}, children: ['BFE'] }, '.dev']
}
]
}
]
}
*/
// Render object literal as DOM tree
const newRoot = render(obj);
console.log(newRoot.outerHTML);
/*
<div>
<h1> this is </h1>
<p class="paragraph">a <button>button</button> from <a href="https://bfe.dev"><b>BFE</b>.dev</a></p>
</div>
*/
As we can see from the console output, the virtualized object and the rendered DOM tree are the same as the original. Therefore, our solution works as expected.