Skip to content

Instantly share code, notes, and snippets.

@mcanam
Created August 11, 2021 11:24
Show Gist options
  • Save mcanam/2e5b33efda3cc9d95e97e82d3b5abfa6 to your computer and use it in GitHub Desktop.
Save mcanam/2e5b33efda3cc9d95e97e82d3b5abfa6 to your computer and use it in GitHub Desktop.
super dom
const xdom = {
bindElement: function(element) {
const props = Object.keys(this);
props.forEach(prop => {
element[prop] = this[prop];
});
return element;
},
select: function(selector) {
const element = document.querySelector(selector);
if (element == null) {
return element;
}
return this.bindElement(element);
},
selectAll: function(selector) {
const elements = document.querySelectorAll(selector);
if (elements.length == 0) {
return elements;
}
elements.forEach(element => {
this.bindElement(element);
});
return elements;
},
create: function(tagName, props = {}) {
const element = document.createElement(tagName);
Object.entries(props).forEach(([prop, value]) => {
if (prop == "attr") {
return this.setAttr(value, element);
}
if (prop == "style") {
return this.addStyle(value, element);
}
if (prop == "event") {
return this.addEvent(value, element);
}
if (prop == "child") {
if (!Array.isArray(value)) value = [value];
value.forEach(child => {
element.appendChild(child);
});
}
if (prop == "parent") {
value.appendChild(element);
}
element[prop] = value;
});
return this.bindElement(element);
},
getAttr: function(attrName, target = this) {
return target.getAttribute(attrName);
},
setAttr: function(attrMap, target = this) {
Object.entries(attrMap).forEach(([key, value]) => {
target.setAttribute(key, value);
});
return this;
},
hasAttr: function(attrName, target = this) {
return target.hasAttribute(attrName);
},
removeAttr: function(attrName, target = this) {
target.removeAttribute(attrName);
return this;
},
toggleAttr: function(attrName, force = false, target = this) {
target.toggleAttribute(attrName, force);
return this;
},
addClass: function(className, target = this) {
target.classList.add(className);
return this;
},
hasClass: function(className, target = this) {
return target.classList.contains(className);
},
removeClass: function(className, target = this) {
target.classList.remove(className);
return this;
},
toggleClass: function(className, target = this) {
target.classList.toggle(className);
return this;
},
addStyle: function(styleMap, target = this) {
if (typeof styleMap == "object") {
Object.entries(styleMap).forEach(([key, value]) => {
target.style[key] = value;
});
return this;
}
let style = this.select("style[xdom]");
if (style == null) {
style = this.create("style", { attr: { xdom: "" } });
document.head.insertAdjacentElement("afterbegin", style);
}
let rules = styleMap;
if (rules.search(/^[#|\.]{1}[\w\s]*\{|[\w\s]*\{/) < 0) {
let selector = target.nodeName.toLowerCase();
if (target.id != "") selector = "#" + target.id;
if (target.className != "") selector = "." + target.className;
rules = `${selector} { ${rules} }`;
}
style = style.sheet;
style.insertRule(rules, style.cssRules.length);
return this;
},
addEvent: function(eventMap, target = this) {
if (!Array.isArray(eventMap)) eventMap = [eventMap];
eventMap.forEach(({name, callback}) => {
target.addEventListener(name, callback);
});
return this;
},
removeEvent: function(eventMap, target = this) {
if (!Array.isArray(eventMap)) eventMap = [eventMap];
eventMap.forEach(({ name, callback }) => {
target.removeEventListener(name, callback);
});
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment