Last active
May 24, 2021 09:40
-
-
Save musicq/b3fd8ac65b5e8a50d3f6c065c5a8a9bb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Given a DOM data structure in JSON | |
* write a function that can render JSON DOM | |
* onto an existing DOM node | |
* It is totally acceptable to google for javascript or dom | |
* manipulation related functions | |
*/ | |
const vDom = { | |
name: "form", | |
tag: "form", | |
children: [ | |
{ | |
tag: "h2", | |
text: "My form", | |
name: "my-form" | |
}, | |
{ | |
tag: "label", | |
text: "First name: " | |
}, | |
{ | |
tag: "input", | |
type: "text", | |
name: "firstName" | |
}, | |
{ | |
tag: "label", | |
text: "Last name: " | |
}, | |
{ | |
tag: "input", | |
type: "text", | |
name: "lastName" | |
}, | |
{ | |
tag: "label", | |
text: "male", | |
children: [ | |
{ | |
tag: "input", | |
type: "radio", | |
name: "gender" | |
} | |
] | |
}, | |
{ | |
tag: "label", | |
text: "female", | |
children: [ | |
{ | |
tag: "input", | |
type: "radio", | |
name: "gender" | |
} | |
] | |
} | |
] | |
}; | |
/** | |
* Answer------------------------------------------------ | |
* function signature | |
* vDom and actual dom are always | |
* passed in pair | |
* @param vDom - Current vDom node | |
* @param element - Current Dom node | |
*/ | |
const render = (vDom, element) => { | |
const dom = createElement(vDom); | |
element.appendChild(dom); | |
}; | |
function createElement(vnode) { | |
const { tag, text, children, ...attrs } = vnode; | |
const el = document.createElement(tag); | |
if (text) { | |
el.appendChild(document.createTextNode(text)); | |
} | |
for (const attr in attrs) { | |
el.setAttribute(attr, attrs[attr]); | |
} | |
if (children) { | |
for (const c of children) { | |
el.appendChild(createElement(c)); | |
} | |
} | |
return el; | |
} | |
// convert data structure | |
let output = { name: "page", tag: "div", children: [1, 2] }; | |
let cache = {}; | |
function genKey() { | |
const seed = Math.random() * 1000; | |
let id = seed.toString(16).substr(4); | |
while (cache[id]) id = genKey(); | |
return id; | |
} | |
function convertData(data, r) { | |
const { children, ...props } = data; | |
let node = { | |
id: genKey(), | |
...props | |
}; | |
if (children) { | |
for (const c of children) { | |
let n = convertData(c, r); | |
node.children = [...(node.children || []), n.id]; | |
} | |
} | |
r.push(node); | |
return node; | |
} | |
// let r = []; | |
// convertData(vDom, r); | |
// console.log(r); | |
/* EOF Answer------------------------------------------------ */ | |
/** | |
* Hint! | |
* The whole program can start off with this call | |
* render(vDom, document.getElementById("main")); | |
*/ | |
render(vDom, document.getElementById("main")); | |
/** | |
* Bonus Question | |
* Given a JSON structure | |
* of pagenation content | |
*/ | |
const pages = { | |
page1: { | |
content: "hello", | |
next: "page2" | |
}, | |
page2: { | |
content: "world", | |
next: "page3" | |
}, | |
page3: { | |
content: "!!!!!", | |
next: "page4" | |
}, | |
page4: { | |
content: "!!!!!", | |
next: "page5" | |
}, | |
page5: { | |
content: "!!!!!" | |
} | |
}; | |
/** | |
* Give this function | |
* for simulating async page load | |
* @param pageName - the page key in JSON structure | |
*/ | |
const fetchPage = (pageName) => | |
new Promise((resolve) => setTimeout(() => resolve(pages[pageName]), 1000)); | |
/** | |
* Expect a promise return array of pages | |
* after all page load complete | |
* | |
* Execution: | |
* yourSolution.then(res=>console.log(res)) | |
* | |
* Expected: | |
* [ {content: "hello", next: "page2"}, | |
* {content: "world", next: "page3"}, | |
* {content: "!!!!!"} ] | |
*/ | |
const getPage = async (next) => { | |
const content = []; | |
const r = await fetchPage(next); | |
content.push(r); | |
if (r.next) content.push(...(await getPage(r.next))); | |
return content; | |
}; | |
getPage("page1").then(console.log); | |
/* EOF Answer------------------------------------------------ */ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment