Skip to content

Instantly share code, notes, and snippets.

@akoppela
Last active June 10, 2023 18:32
Show Gist options
  • Save akoppela/8a19d9b039e9af21c4b27b5c4c998782 to your computer and use it in GitHub Desktop.
Save akoppela/8a19d9b039e9af21c4b27b5c4c998782 to your computer and use it in GitHub Desktop.
Custom Elements with ES5 syntax

You'll need to include two pollyfils before you include a code with your custom elements:

webcomponents/webcomponentsjs/custom-elements-es5-adapter.js - this is for new browsers in order to understand ES5 syntax

webcomponents/custom-elements/custom-elements.min.js - this is for old browsers without customElements support

You can add them to your index.html file in the following way:

<div id="custom-elements-adapter">
    <!-- Trick to include custom elements es5 adapter only if custom elements are supported -->
    <script type="text/javascript">
        if ('customElements' in window === false) {
            var adapter = document.getElementById('custom-elements-adapter');

            adapter.parentNode.removeChild(adapter);
            adapter = undefined;
        }
    </script>
    <script type="text/javascript" src="vendor/custom-elements-es5-adapter.js"></script>
</div>

<div id="custom-elements-polyfill">
    <!-- Trick to include custom elements polyfill only if custom elements are not supported -->
    <script type="text/javascript">
        if ('customElements' in window) {
            var polyfill = document.getElementById('custom-elements-polyfill');

            polyfill.parentNode.removeChild(polyfill);
            polyfill = undefined;
        }
    </script>
    <script type="text/javascript" src="vendor/custom-elements.min.js"></script>
</div>
/**
* `my-custom-element` is very basic custom element.
*
* @param {ParentInstance} [self] Parent instance from which we want to inherit from.
* @returns {MyCustomElementInstance} Your custom element instance.
*/
function MyCustomElement(self) {
// Equivalent of super call.
// This is needed on order to create `myCustomElement` element from JS
self = HTMLElement.call(self || this);
// Here initialization logic can be used.
...
return self;
}
// List of observed attributes should be specified in order for `attributeChangedCallback` to be called
// This is static definition of property. Static functions could be defined in the same way.
MyCustomElement.observedAttributes = [‘attributeName’, ‘anotherAttributeName’];
// This is how you can create a prototype of your custom element. In this case it extends native HTMLElement.
MyCustomElement.prototype = Object.create(HTMLElement.prototype, {
// An instance of the element is created or upgraded.
// Useful for initializing state, settings up event listeners.
constructor: {
// This specifies that the value for the `constructor` is `MyCustomElement`.
value: MyCustomElement
},
// Called every time the element is inserted into the DOM.
// Useful for running setup code, such as fetching resources or rendering.
// Generally, you should try to delay work until this time.
connectedCallback: {
// This specifies that the value of `connectedCallback` is a function with some setup logic.
value: function () {
...
}
},
// Called every time the element is removed from the DOM.
// Useful for running clean up code.
disconnectedCallback: {
// This specifies that the value of `disconnectedCallback` is a function with some clean up logic.
value: function () {
...
}
},
// Called when an observed attribute has been added, removed, updated, or replaced.
// Also called for initial values when an element is created by the parser, or upgraded.
// Note: only attributes listed in the `observedAttributes` property will receive this callback.
attributeChangedCallback: {
// This specifies that the value of `attributeChangedCallback` is a function with some logic.
value: function (name, oldValue, newValue) {
...
}
},
// Like this yuo can define any properties of the component so that you can access them later.
propertyName: {
// Like this you can defined a function which will be called when you want to get a property of the component.
// E.g. `element.value`, `element.src` or `element.propertyName`.
get: function () {
return ...;
},
// Like this you can defined a function which will be called when you want to set a property of the component.
// E.g. `element.value = 'new value'`, `element.src = 'new src'` or `element.propertyName = 'some property'`.
set: function (value) {
...
}
},
// Like this you can define any methods of the component so that you can call them later.
// E.g. `element.hide()`, `element.print()` or `element.methodName()`.
methodName: {
// This specifies that the value of `methodName` is a function with some logic.
value: function () {
...
}
}
});
// Defines `my-custom-element` custom element
window.customElements.define(‘my-custom-element’, MyCustomElement);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment