Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Explosion-Scratch/1e2e7c087e324e39659f78ef4da87267 to your computer and use it in GitHub Desktop.
Save Explosion-Scratch/1e2e7c087e324e39659f78ef4da87267 to your computer and use it in GitHub Desktop.
/**
* Creates a custom HTML element and appends it to a container element.
*
* @param {{tag: string, container: HTMLElement, name: string, style: string, placement: string}} options
* @param {string} options.tag - The tag name of the element to create (default: "div").
* @param {HTMLElement} options.container - The container element where the new element will be appended.
* @param {string} options.name - The name of the custom element.
* @param {string} [options.style=""] - The CSS styles to apply to the custom element.
* @param {string} [options.placement="beforeend"] - The placement of the new element relative to the container (beforebegin, afterbegin, beforeend, afterend).
* @returns {{el: HTMLElement, document: DocumentFragment, stylesheet: CSSStyleSheet}} - An object containing the created element, its shadow root, and the stylesheet.
*
* @throws {Error} If either the container or name options are not provided.
*
* @example
* const container = document.getElementById("my-container");
* const result = createElement({
* tag: "span",
* container,
* name: "my-custom-element",
* // Won't impact elements on the main page, similarly styles in the main page won't impact the span
* style: "* {color: red;}",
* placement: "beforeend"
* });
* console.log(result.el); // The created <span> element
* console.log(result.document); // The shadow root of the custom element
* console.log(result.stylesheet); // The stylesheet with the applied CSS rules
*/
function createElement({tag = "div", container, name, style = "", placement = "beforeend"}) {
if (!(name && container)){throw new Error("Container and name required")}
if (!customElements.get(name)) {
class CustomElement extends HTMLElement {
constructor() {
super();
this.shadow = this.attachShadow({ mode: "open" });
}
}
customElements.define(name, CustomElement);
}
const customElement = document.createElement(name);
const newElement = document.createElement(tag);
customElement.shadow.appendChild(newElement);
if (style) {
const stylesheet = new CSSStyleSheet();
stylesheet.replaceSync(style);
customElement.shadowRoot.adoptedStyleSheets = [stylesheet];
}
container.insertAdjacentElement(placement, customElement);
return { el: newElement, document: customElement.shadowRoot, stylesheet };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment