Here is a simple custom element:
class TestElement extends HTMLElement {
backingField;
get property() { return this.backingField; }
set property(value) {
this.backingField = value;
console.log("Inside Setter");
}
constructor() {
super();
const template = document.createElement("template");
template.innerHTML = "<input>";
this.attachShadow({ mode: "open" });
this.shadowRoot.appendChild(template.content.cloneNode(true));
}
}
window.customElements.define("test-element", TestElement);
// Parsing the element
const element = new DOMParser().parseFromString("<test-element></test-element>", "text/html").body.childNodes[0];
// Accessing the setter
element.property = "test";
document.body.appendChild(element);
When setting the property (element.property = "test"
), Inside Setter
should presumably be printed to the console. However, it does not.
When creating the element using document.createElement()
, it works, but I need the element to be parsed.
How to solve this?
Edit:
When I set the property after appending the element to the body
, it works:
document.body.appendChild(element);
element.property = "test";
I am not sure what is happening. I really need to set the property before it is appended to the document.
Well you created a custom element and registered it to the window, meaning it will be available in the page's DOM, (window.document).
However, how the DOMParser works is by creating another DOM object with its own data independent from the page DOM. Any custom elements you defined in the page DOM will not be accessible in this separate DOM.
If you want to take an element from the DOM created by the DOMParser and import it into the page DOM (without appending it), you can use the Document.importNode()
method.
From MDN:
The
Document
object'simportNode()
method creates a copy of aNode
orDocumentFragment
from another document, to be inserted into the current document later.
So in your existing code, make sure to call this method before inserting the element into the document. This way, the custom element defined in the page's DOM will be recognized.
const element = document.importNode(new DOMParser().parseFromString("<test-element></test-element>", "text/html").body.childNodes[0]);
element.property = "test";
document.body.appendChild(element);