Is it possible to modify a custom element / web component class after it's been registered? This isn't something I'll typically (or ever) want to do in production code, but when prototyping or implementing a code-patching tool for development, it'd be useful. Here's what I've tried, unsuccessfully, so far:
document.body.appendChild(document.createElement('foo-bar')) // empty element
class FooBar extends HTMLElement {
connectedCallback () {
this.textContent = 'foo bar'
}
}
customElements.define('foo-bar', FooBar) // element shows "foo bar"
FooBar.protoype.connectedCallback = function () {
this.textContent = 'foo bar 2'
}
document.body.appendChild(document.createElement('foo-bar')) // element shows "foo bar", not "foo bar 2"
customElements.get('foo-bar').protoype.connectedCallback = function () {
this.textContent = 'foo bar 2'
}
document.body.appendChild(document.createElement('foo-bar')) // element shows "foo bar", not "foo bar 2"
class FooBar2 extends HTMLElement {
connectedCallback () {
this.textContent = 'foo bar 2'
}
}
customElements.define('foo-bar', FooBar2) // Exception thrown, 'foo-bar' already defined
In summation, modifying the class originally passed to the CustomElementsRegistry has no effect. Assigning to the prototype of what's in the registry has no effect. Attempting to assign a new class to the element in the registry isn't possible as an exception is thrown. All three of these behaviors are counter to my experience with almost every aspect of every other JavaScript API. It's extremely unusual, for better or worse, to not be able to mutate something unless it's set to be non-configurable. However, when I inspect if the objects are configurable, the runtime says they are!
Does anyone know of a way to modify/augment a custom element definition after it's been defined?
Custom elements cannot be self-closing because HTML only allows a few elements to be self-closing. Always write a closing tag ( <app-drawer></app-drawer> ).
The customElements. get() method can be used to check whether a given custom element has already been registered in the page. This can be used to find whether a given custom element name is available in the page or not, and prevent clashes with another custom element.
“What's The Point Of Custom Elements?” The basic idea is that if you create an element that always performs the same role and has the same set of properties and functions applied to it, then you should be able to name it after what it does.
There is no way to change a tag once defined, seems like it pulls in the class when defined.
I have found a way to dynamically reload the code behind a custom element by placing a wrapper class as the constructor, I now have hot reloading on custom elements, no more refreshing apps - the wrapper will need to handle attribute bubbling etc
basically you need to rely on the following pieces
knowing what elements are not defined, ideally called whenever you performing changes to the DOM, alternatively you could place a setInterval for development.
document.querySelectorAll(':not(:defined)')
define the custom element inline so you can use the same constructor for ALL custom elements. customElements.define(elementName, class extends HTMLElement {...
document.querySelectorAll(':not(:defined)').forEach((ele, k) => {
let elementName = ele.tagName.toLowerCase();
if (!customElements.get(elementName)) {
//defining custom element
customElements.define(elementName, class extends HTMLElement {
constructor() {
super();
}
disconnectedCallback() {
if (this._elementClass) {
this._elementClass.disconnectedCallback()
}
}
connectedCallback() {
let element = (this.tagName).toLowerCase();
//reload the class variable here eg: importScript/getScripts
//dependent on whatever variable you want eg: cache id or
//then make calls to the customElement class
this._elementClass = new NodeTest(this);
this._elementClass.connectedCallback();
...
var NodeTest = class {
constructor(ele) {
this.ele = ele;
}
disconnectedCallback() {
}
connectedCallback() {
this.render();
}
render() {
this.ele.innerHTML = '<h1>hheee</h1>';
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With