LittleToDo
JavaScript HTML Components Without Frameworks
HTML
<div id="todos">
</div>
JavaScript
const Mixins = {
// return attribute value
getAttribute(name) {
// if nothing on object itself, use built-in getAttribute
if(typeof(this[name])==="undefined") {
return HTMLElement.prototype.getAttribute.call(this,name);
}
return this[name];
},
// set attribute on object
// extra argument lazy=true if change should not be reactive
setAttribute(name,value,lazy) {
// auxiliary test function
const equal = (a,b) => {
const typea = typeof(a),
typeb = typeof(b);
// same type and one of
return typea === typeb &&
// identical
(a===b ||
// same length, size, order
(Array.isArray(a) && Array.isArray(b) && a.length===b.length
&& a.every((item,i) => b[i]===item)) ||
// all keys the same
(a && b && typea==="object" &&
Object.keys(a).every(key => equal(a[key],b[key])) &&
Object.keys(b).every(key => equal(a[key],b[key]))));
};
let type = typeof(value),
oldvalue = this.getAttribute(name);
const neq = !equal(oldvalue,value);
// only make changes if new and old value are not equal
// or change is non-reactive
if(neq || lazy) {
// remove object property and attribute is value is null
if(value==null) delete this[name]; this.removeAttribute(name);
// add to object if type is object
if(type==="object") this[name] = value;
// otherwise, use built-in setAttribute
else HTMLElement.prototype.setAttribute.call(this,name,value);
}
// render if !lazy (i.e. is reactive), renderable, value changed
if(!lazy && this.render && neq) this.render();
},
// not a great id generator, but good enough for demo
genId() {
return "id" + (Math.random()+"").substring(2);
}
}
const ToDoView = function({title="",listid="",done=false},
el = document.createElement("todo")){
const attributes = {title,listid,done,...arguments[0]};
...