Skip to main content
Megh's Blog

Javascript's using statement & a spinner using aria-busy

JS's new using statement works very well as a loading indicator with minimal CSS frameworks like PicoCSS & Oat.Ink which use aria-busy to show a loading indicator.

See the Pen Untitled by Megh Parikh (@meghprkh) on CodePen.

This trick lets you add a spinner to the clicked button or result container, and optionally disable the button while it runs. It also destroys the loading indicator if there was an error when using with try/catch.

The using statement is not baseline yet. caniuse using

Note: HTMX's has this utility as data-loading-aria-busy in its loading-states extension

Full Code #

/// Usage: `using _loading = new LoadingIndicator(element, disable?)`
/// Where `element` is the element to add the LoadingIndicator to and disable is
/// whether to disable the element
class LoadingIndicator {
	#element;
	#disable;
	constructor(element, disable = false) {
		this.#element = element;
		this.#disable = disable;
		this.#element.setAttribute("aria-busy", "true");
		if (this.#disable) this.#element.setAttribute("disabled", "true");
	}
	[Symbol.dispose]() {
		this.#element.removeAttribute("aria-busy");
		if (this.#disable) this.#element.removeAttribute("disabled");
	}
}

Example Usage

document.querySelector("myBtn").addEventListener("click", async (e) => {
	const response = document.querySelector("#response");
	try {
		using _loading = new LoadingIndicator(e.target, true);
		using _loading2 = new LoadingIndicator(response, true);
		const res = await fetch("https://httpbin.org/delay/2");
		response.innerHTML += "<p>Hello world!</p>";
	} catch {
		response.innerHTML += "<p>Failed fetching!</p>";
	}
});
<link
	rel="stylesheet"
	href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"
/>

<main class="container">
	<button id="myBtn">Click me!</button>
	<article id="response">
		<h2>Response</h2>
	</article>
</main>

Other minimal JS tricks I found useful #

While building a small web frontend for a WASM playground around a CLI tool, I explored this and a few related stuff. It was a great experience working within the no-build web ecosystem.