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)