Created
July 23, 2024 22:06
-
-
Save Explosion-Scratch/1e2e7c087e324e39659f78ef4da87267 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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