So I know how to create a custom element and have 2 already made that I'm happy with. My two elems look something like this:
let menuPicker = Object.create(HTMLElement.prototype);
menuPicker.initialized = false;
menuPicker._init = function(){
...
}
...
menuPicker.attachedCallback = menuPicker._init;
menuPicker.createdCallback = menuPicker._init;
...
document.registerElement('menu-picker', {
prototype: menuPicker
});
Which works and all, but this time around I want a JS class. Specifically this feature:
class test {
get item(){...}
set item(){...}
}
So I figured I could just do the following to easily implement this.
class listBox extends HTMLElement.prototype {
initialized = false;
constructor(props){
super(props);
this.attachedCallback = this._init;
this.createdCallback = this._init;
}
_init () {
if(this.initialized) return;
this.initialized = true;
this.style.display = "block";
this.appendChild(document.createElement('div'));
}
}
document.registerElement('list-box', {
prototype: listBox
});
However I get the error Class extends value #<HTMLElement> is not a constructor or null
.
So now I'm stuck and can't find a method of using a class to construct a custom HTML element.
To simplify:
How do I create a custom element using a JS class to create the properties for the element?
Here is an example to create a custom element
//ListBox.js
export default class ListBox extends HTMLElement {
// observe attributes of custom element
static get observedAttributes() {
return ["disp", "text"];
}
get myAction() {
return this.hasAttribute("open");
}
set myAction(val) {
if (val) {
this.setAttribute("open", "");
} else {
this.removeAttribute("open");
}
}
constructor() {
super();
this.initialized = false;
this.div = document.createElement("div");
// get and assigns value from props "disp"
this.div.style.display = this.getAttribute("disp");
// get and assigns value from props "text"
this.div.innerHTML = this.getAttribute("text");
this.appendChild(this.div);
}
connectedCallback() {
// didMount
// your methode here
this.initialized = true;
console.log("custom element added to page");
}
disconnectedCallback() {
// unmount
console.log("custom element remove from page");
}
attributeChangedCallback(name, oldValue, newValue) {
// observed props
console.log("props", arguments);
// get and assigns value from props "text"
if (name === "text" && oldValue !== newValue) {
this.div.innerHTML = newValue;
}
}
}
in your html in the script tag which calls your index.js add type="module"
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="app">
<list-box text="Some text here" disp="block"></list-box>
</div>
<script src="src/index.js" type="module"></script>
</body>
</html>
In your index.js import your component and do Something
import ListBox from "./component/ListBox";
customElements.define("list-box", ListBox);
// change props "text value"
document
.querySelector("list-box")
.setAttribute("text", `Change the value of props "text"`);