From 508601379662e8d227d76f4ec23cdf227e10665e Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Sun, 3 May 2020 11:55:42 +0300 Subject: [PATCH] Add renderElement snippet --- snippets/renderElement.md | 54 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 snippets/renderElement.md diff --git a/snippets/renderElement.md b/snippets/renderElement.md new file mode 100644 index 000000000..b941fdcbe --- /dev/null +++ b/snippets/renderElement.md @@ -0,0 +1,54 @@ +--- +title: renderElement +tags: browser,recursion,advanced +--- + +Renders the given DOM tree in the specified DOM element. + +Destructure the first argument into `type` and `props`, use `type` to determine if the given element is a text element. +Based on the element's `type`, use either `Document.createTextNode()` or `Document.createElement()` to create the DOM element. +Use `Object.keys(props`, adding attributes to the DOM element and setting event listeners, as necessary. +Use recursion to render `props.children`, if any. +Finally, use `Node.appendChild()` to append the DOM element to the specified `container`. + +```js +const renderElement = ({ type, props = {} }, container) => { + const isTextElement = !type; + const element = isTextElement + ? document.createTextNode('') + : document.createElement(type); + + const isListener = p => p.startsWith('on'); + const isAttribute = p => !isListener(p) && p !== 'children'; + + Object.keys(props).forEach(p => { + if(isAttribute(p)) element[p] = props[p]; + if(!isTextElement && isListener(p)) + element.addEventListener(p.toLowerCase().slice(2), props[p]); + }); + + if(!isTextElement && props.children && props.children.length) + props.children.forEach(childElement => renderElement(childElement, element)); + + container.appendChild(element); +} +``` + +```js +const myElement = { + type: 'button', + props: { + type: 'button', + className: 'btn', + onClick: () => alert('Clicked'), + children: [ + { props: { nodeValue: 'Click me' } } + ] + } +}; + +renderElement( + myElement, + document.body +); +```