Functional DOM Manipulation
Build A Functional DOM Manipulation Toolkit and a Todo App Demo with it.
The Toolkit
const SVG_NS = 'http://www.w3.org/2000/svg'; export const el = type => document.createElement(type); export const svg = type => document.createElementNS(SVG_NS, type); export const text = value => document.createTextNode(value); export const append = (parent, children) => { const fragment = document.createDocumentFragment(); fragment.append(...children); parent.appendChild(fragment); }; export const appendChild = (parent, child) => parent.appendChild(child); export const attr = (node, name, value) => { if(!value) { node.removeAttribute(value); return; } node.setAttribute(name, value); }; export const addClass = (node, ...classNames) => node.classList.add(...classNames); export const setTextContent = (node, text) => node.textContent = text; export const on = (node, type, handler) => node.addEventListener(type, handler); export const off = (node, type, handler) => node.removeEventListener(type, handler);
TODO APP DEMO
import { el, on, off, setTextContent, text, attr, addClass, append, appendChild } from './tookit.js'; const createDeleteTodoBtn = handleTodoDelete => { const deleteTodoBtn = el('button'); setTextContent(deleteTodoBtn, 'Delete Todo'); const handleDelete = () => { off(deleteTodoBtn, 'click', handleDelete); handleTodoDelete(); }; on(deleteTodoBtn, 'click', handleDelete); return deleteTodoBtn; }; const createTodo = ({ todo, id }) => { const todoItem = el('li'); const todoText = text(todo); const handleDelete = () => { todoItem.remove(); // do cleanup stuff }; const deleteTodoBtn = createDeleteTodoBtn(handleDelete); addClass(todoItem, 'todo'); attr(todoItem, 'data-id', id); append(todoItem, [todoText, deleteTodoBtn]); return todoItem; }; const createTodoList = data => { const todoList = el('ul'); addClass(todoList, 'todo-list'); const todos = data.map(createTodo); append(todoList, todos); return todoList; }; const createTodoForm = handleForm => { const todoForm = el('div'); addClass(todoForm, 'todo-form'); const todoInput = el('input'); const handleSubmit = e => { e.preventDefault(); const todo = todoInput.value; if(!todo) { return; } handleForm({ todo, id: crypto.randomUUID(); }); }; on(todoForm, 'submit', handleSubmit); return todoForm; }; const createTodoApp = initialData => { const appContainer = el('div'); addClass(appContainer, 'todo-app'); const todoList = createTodoList(initialData); const handleFormSubmit = todo => { appendChild(todoList, createTodo(todo)); }; const todoForm = createTodoForm(handleFormSubmit); append(appContainer, [todoForm, todoList]); return appContainer; };
Top comments (0)