How to Separate Web Components to Individual Files and Load Them

How to separate web components to individual files and load them?

In the main file, use <script> to load the Javascript file x-counter.js.

In the Javascript file, use fetch() to load the HTML code x-counter.html.

In the HTML file, use <link rel="stylesheet"> to load the CSS file x-counter.css.

CSS file : x-counter.css

button, p {
display: inline-block;
color: dodgerblue;
}

HTML file : x-counter.html

<link rel="stylesheet" href="x-counter.css">
<button aria-label="decrement">-</button>
<p>0</p>
<button aria-label="increment">+</button>

Javascript file : x-counter.js

fetch("x-counter.html")
.then(stream => stream.text())
.then(text => define(text));

function define(html) {
class XCounter extends HTMLElement {
set value(value) {
this._value = value;
this.valueElement.innerText = this._value;
}

get value() {
return this._value;
}

constructor() {
super();
this._value = 0;

var shadow = this.attachShadow({mode: 'open'});
shadow.innerHTML = html;

this.valueElement = shadow.querySelector('p');
var incrementButton = shadow.querySelectorAll('button')[1];
var decrementButton = shadow.querySelectorAll('button')[0];

incrementButton.onclick = () => this.value++;
decrementButton.onclick = () => this.value--;
}
}

customElements.define('x-counter', XCounter);
}

Main file : index.html

<html>
<head>
<!-- ... -->
<script src="x-counter.js"></script>
</head>
<body>
<x-counter></x-counter>
</body>
</html>

How to combine HTML web component with HTML file? innerHTML = foo(myfile.html)

You can do it with fetch().

Note that it's an asynchronous function so you should use async/await or Promise().

this.innerHTML = await fetch( 'myfile.html' ).then( s => s.text() )

2 implementation examples for Web Components:

  • a minimal example with async/await,
  • a more complete one with Promise.

Creating a simple web component that injects a HTML line and runs a JS function

You're almost there, to expand on your implementation we can use basic Javascript to create custom HTML components using the HTMLElement interface. Also, take a look in the HTML living standard specification for some more examples and implementations.

As an example, we can first define the new custom component and its functionality in Javascript (This can be done in the tag in your HTML or in a separate external js file).

class MyComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = `<h1>Hello world</h1>`;
}
}

customElements.define('my-web-component', MyComponent);
<body>
<my-web-component></my-web-component>
</body>

Combining Web Component Script References Within a Single File

Simply import them as ES Modules. Create a file components.js right next to your index.html:

import { ScheduleManager } from 'web-components/ScheduleManager.js';
import { ActionButtons } from 'web-components/ActionButtons.js';
import { DetailsPane } from 'web-components/DetailsPane.js';
import { PageHeaderLinks } from 'web-components/PageHeaderLinks.js';
import { SideBarHeader } from 'web-components/SideBarHeader.js';
import { JobsTableHeader } from 'web-components/JobsTableHeader.js';
import { ModuleMenus } from 'web-components/ModuleMenus.js';
import { SelectDetailsPane } from 'web-components/SelectDetailsPane.js';

In your webcomponents files, export the classes, example:

export class ScheduleManager extends HTMLElement {

Last step: Link the components.js in your HTML with type="module" in the <head>:

<script src="./components.js" type="module"></script>

Vanilla WebComponents approaches: is there any real difference between importing js from html and fetching html from js file

If you don't plan to use your custom element in various pages then the 2 solutions are good.

In the first one it could be faster because you will save an HTTP request, for the HTML template is immediately available in the main HTML page.

But if you plan to reuse the custom element (or for better code separation), the second solution is better because the consumer is separated from the web component.



Related Topics



Leave a reply



Submit