Skip to content

Instantly share code, notes, and snippets.

@smart-onion
Created May 20, 2025 11:01
Show Gist options
  • Save smart-onion/feb328f4e9fa11ac81fe763a0777e45a to your computer and use it in GitHub Desktop.
Save smart-onion/feb328f4e9fa11ac81fe763a0777e45a to your computer and use it in GitHub Desktop.
JS5
class HtmlElement {
#tagOpen;
#tagClose;
constructor(name, paired = true) {
this.name = name;
this.paired = paired;
this.textContent = "";
this.children = [];
this.attributes = [];
this.styles = []
this.events = [];
this.#tagOpen = paired ? `<${name}>` : `<${name} />`;
this.#tagClose = paired ? `\n</${name}>` : "";
}
setAttribute({name=undefined, value=undefined} = {}){
this.attributes.push({name: name, value: value});
return this;
}
setStyle({name=undefined, value=undefined} = {}){
this.styles.push({name: name, value: value});
let styles = this.styles.map(style => style.name + ":" + style.value).join( ";")
if(this.attributes.length === 0) {
this.attributes.push({name: "style", value: styles});
return this;
}
this.attributes.forEach(attr => {
if(attr.name === "style"){
attr.value = styles;
}
})
return this;
}
prependElement(element){
element.#tagOpen += "ss" + element.#tagOpen;
this.children.unshift(element);
}
appendElement(element){
this.children.push(element);
}
#setTagOpen(){
this.#tagOpen = `<${this.name}`;
this.attributes.forEach(attr => {
this.#tagOpen += ` ${attr.name}="${attr.value}"`;
})
this.#tagOpen += ">"
}
getHtml(){
this.#setTagOpen();
return this.#tagOpen +
this.textContent +
this.children.map(child => child.getHtml()).join("") +
this.#tagClose;
}
}
let div = new HtmlElement("div");
div.setAttribute({name: "id", value: "root"});
div.setAttribute({name: "class", value: "root"});
div.setAttribute({name: "data-test", value: "test"});
let p2 = new HtmlElement("div");
p2.setStyle({name: "color", value: "red"});
p2.setStyle({name: "color", value: "red"});
p2.setStyle({name: "width", value: "10px"});
p2.setAttribute({name: "data-test", value: "test"});
let p3 = new HtmlElement("p");
p3.textContent = "Hello world!";
p3.setStyle({name: "color", value: "red"});
p3.setAttribute({name: "data-test", value: "test"});
div.prependElement(p2);
p2.appendElement(p3);
let elem = document.createElement("div");
elem.innerHTML = div.getHtml(); // browser reading as actual html
console.log(div.getHtml());
class CssClass{
constructor(name){
this.name = name;
this.styles = [];
}
addStyle(name, value){
this.styles.push({name: name, value: value});
}
removeStyle(name){
this.styles.forEach((style, index) => {
if(style.name === name){
this.styles.splice(index);
}
})
}
getCss(){
return `${this.name}{ ${this.styles.map(style => `${style.name}:${style.value}`).join(";")} }`;
}
}
let css = new CssClass(".root");
css.addStyle("color", "red");
css.addStyle("width", "10px");
class HtmlBlock{
constructor(html,css) {
this.html = html;
this.css = new HtmlElement("style");
this.css.textContent = css;
}
getCode(){
return this.css.getHtml() + this.html;
}
}
let html = new HtmlBlock(div.getHtml(), css.getCss());
console.log(html.getCode());
elem.innerHTML = html.getCode(); // browser reading as actual html
document.body.appendChild(elem);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment