Hi there!
This is a very good question with unfortunately a slightly unsatisfying answer, unless you were to ask this on a very cough opinionated cough platform such as “The Orange Site” or “The Blue Bird’s Site”.
Regarding style
Even though people would like to argue that whatever style they adopted is the best, unfortunately, JavaScript (and the broader ECMAScript) has no official nor defacto standard. I would argue that in recent years the following three are still commonplace:
- The AirBnB style guide which you’ve already linked
- StandardJS
- Whatever Prettier + ESLint : recommends has as default
In the end, these are styles and not standards (despite StandardJS being called Standard). FAANG cannot agree which one to adopt, and thus generally I recommend adding ESLint and Prettier so you don’t need to think about most of it. The recommended set of ESLint rules isn’t that opinionated and majority of people agrees on it.
Regarding button clicks
There is a problem with onClick
which, apart from “polluting” the HTML element with string-encoded-JavaScript which needs to be evaluated. You cannot mark attribute-provided scripts as safe using a nonce, which means you cannot adopt CSP if you wanted to.
The second problem with the onclick
attribute is that it can hold at most one click listener. In general not an issue, but there are plenty of cases where you want to add more than one event listener to a specific DOM element.
So what do we do?
- Use
element.addEventListener('click', ...)
- Use something unobtrusive like Stimulus
For example, here is an implementation of that last framework for a print button, which is hidden if the window.print()
functionality isn’t available:
import { toggleHidden } from 'src/utils/dom-toggle';
import { Controller } from 'stimulus';
/**
* Allows a button to open the print dialog, if this feature is enabled.
*
* This controller automatically removes the hidden attribute if printing
* is enabled, and leaves it in place if there is no printing API, or if
* JavaScript is disabled.
*
* You can use the print: modifier to change the CSS on the page when printed.
*
* @example The HTML for a minimal example
*
* <button
* hidden
* data-controller="print"
* data-action="print#onPrint"
* type="button"
* class="button --primary print:hidden whitespace-nowrap">
* <svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 -ml-1 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
* <path stroke-linecap="round" stroke-linejoin="round" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
* </svg>
* <span>
* Print
* </span>
* </button>
*/
export default class PrintController extends Controller {
static targets = ['trigger'];
private declare triggerTarget: HTMLButtonElement;
private declare hasTriggerTarget: boolean;
public connect(): void {
// Show element if printing is possible
if (window && 'print' in window && typeof window.print === 'function') {
toggleHidden(this.element, false);
if (this.hasTriggerTarget) {
toggleHidden(this.triggerTarget, false);
}
}
}
public disconnect(): void {
toggleHidden(this.element, true);
if (this.hasTriggerTarget) {
toggleHidden(this.triggerTarget, true);
}
}
public onPrint(): void {
window.print();
}
}
You would use this by adding the following HTML:
<button
hidden
data-controller="print"
data-action="print#onPrint"
type="button"
class="button --primary print:hidden whitespace-nowrap">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 -ml-1 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
<path stroke-linecap="round" stroke-linejoin="round" d="M17 17h2a2 2 0 002-2v-4a2 2 0 00-2-2H5a2 2 0 00-2 2v4a2 2 0 002 2h2m2 4h6a2 2 0 002-2v-4a2 2 0 00-2-2H9a2 2 0 00-2 2v4a2 2 0 002 2zm8-12V5a2 2 0 00-2-2H9a2 2 0 00-2 2v4h10z" />
</svg>
<span>
Print
</span>
</button>
This button will show “itself” when the JavaScript loads, but only if the print
function is available. In my opinion, this is a very good way to write JavaScript, in general.
Conclusion
In general, I would ignore anyone who says “this is the number 1 way to do x” because the beauty of this language is that there are always 10 equally shitty ways to do it. I merely recommend you pick a style, and stick to it. The AirBnB guide is pretty strict (and overwhelming, and in my opinion not always right), so I would go for a looser approach, like prettier + eslint, but YMMV.