I'm trying to create a web component that extends the div element and I found this other Stack Overflow question about how to extend native elements (a button in this case). However, I cannot make it work. And, according to the update in this answer, it should work.
If you look at the results in this simplified code snippet, it is just rendered as a simple inline element with text. And if you open the Chrome console and look in the properties tab it is also clear that it does not inherit from HTMLButtonElement (which it should). What's wrong?
class FancyButton extends HTMLButtonElement {
constructor() {
super(); // always call super() first in the ctor.
this.addEventListener('click', e => this.innerHTML = "I was clicked");
}
}
customElements.define('fancy-button', FancyButton, { extends: 'button' });
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>title</title>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body>
<fancy-button>Click me</fancy-button>
</body>
</html>
We can avoid them using libraries like Lit, Stencil, or Catalyst. The realization that all modern frontend frameworks and many big companies count on Web Components clearly shows that Web Components are not dead.
In the HTML DOM, the Element object represents an HTML element, like P, DIV, A, TABLE, or any other HTML element.
AFAIK
There are 2 types of Custom Elements MDN: Using Custom Elements
One registry to rule them all
There is only one registry so your Customized element is registered as fancy-button
;
But can NOT* be used with Autonomous notation: <fancy-button></fancy-button/>
* Firefox DOES allow a mix of both notations BUT only if define() is used AFTER element usage
https://developers.google.com/web/fundamentals/web-components/customelements#extendhtml
Consumers of a customized built-in element can use it in several ways.
They can declare it by adding the is="" attribute on the native tag:
<!-- This <button> is a fancy button. -->
<button is="fancy-button" disabled>Fancy button!</button>
create an instance in JavaScript:
// Custom elements overload createElement() to support the is="" attribute.
let button = document.createElement('button', {is: 'fancy-button'});
button.textContent = 'Fancy button!';
button.disabled = true;
// have to do this yourself!! IF you want to use it as a selector
button.setAttribute("is","fancy-button");
document.body.appendChild(button);
or use the new operator:
let button = new FancyButton();
button.textContent = 'Fancy button!';
button.disabled = true;
There are 2 types of Custom Elements, you can't mix
You either go for:
<fancy-button></fancy-button>
or
<button is=fancy-button></button>
document.createElement('fancy-button') instanceof HTMLButtonElement
returns false
and
<fancy-button>lightDOM</fancy-button>
document.querySelector('fancy-button')
returns the element (if in the DOM),
but the element is processed as an undefined Element displaying the lightDOM contents
In https://cardmeister.github.io I used both:
<card-t rank=queen suit=hearts></card-t>
<img is=queen-of-hearts/>
Thus I could not do:
<queen-of-hearts></queen-of-hearts>
The latter has little value, with IMG the is
attribute can be used for CSS targetting.
CSS Selector for a partial CustomElement nodename
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