dom-controller
v1.0.1
Published
Adds controller logic to elements through attributes
Maintainers
Readme
dom-controller
Attach behavior to any HTML element using just an attribute.
dom-controller connects JavaScript logic to DOM elements declaratively — no inline scripts, no global code, just clean HTML and modular controllers.
📦 Less than 2KB minified + gzipped
Used in production across multiple projects. Battle-tested and ready to ship.
🚀 Quick Start
1. Load the library
<script
src="https://unpkg.com/[email protected]/bundle.min.js"
defer
></script>2. Link your controller
<link
controller-name="click-counter"
href="/controllers/click-counter.mjs"
/>3. Use it in HTML
<button controller="click-counter">Clicked 0 times</button>4. Write the controller
// /controllers/click-counter.mjs
export default class ClickCounterController {
count = 0;
async attach(element) {
this.element = element;
element.addEventListener('click', this.onClick.bind(this));
}
async detach(element) {
element.removeEventListener('click', this.onClick.bind(this));
}
onClick() {
this.count++;
this.element.textContent = `Clicked ${this.count} times`;
}
}✍️ TypeScript Example
// /controllers/click-counter.ts
import { IController } from 'dom-controller/IController';
export default class ClickCounterController implements IController<HTMLElement> {
count = 0;
async attach(element: HTMLElement): Promise<void> {
element.addEventListener('click', this.onClick.bind(this));
}
async detach(element: HTMLElement): Promise<void> {
element.removeEventListener('click', this.onClick.bind(this));
}
onClick() {
this.count++;
this.element.textContent = `Clicked ${this.count} times`;
}
}⚙️ Alternative: Classic Script Loading
If you're not using ES modules, you can register the controller manually:
<head>
<script src="https://unpkg.com/[email protected]/bundle.min.js" defer></script>
<script src="/controllers/click-counter.js" defer></script>
</head>// /controllers/click-counter.js
class ClickCounterController {
count = 0;
attach(element) {
element.addEventListener('click', this.onClick.bind(this));
}
detach(element) {
element.removeEventListener('click', this.onClick.bind(this));
}
onClick() {
this.count++;
this.element.textContent = `Clicked ${this.count} times`;
}
}
DomController.registerController(ClickCounterController, 'click-counter');✅ Features
- Declarative behavior with
controller="name" - Simple and portable controller classes
- Works with modules or classic scripts
- TypeScript support out of the box
- No framework or build step required
