Code Explainers

Code explainers tagged #dom

javascript
function attachThousandSeparators(input, { locale = 'en-US' } = {}) {
  const formatter = new Intl.NumberFormat(locale);
  const groupSep = formatter.format(11111).replace(/\d/g, '')[0] || ',';
  const decimalSep = formatter.format(1.1).replace(/\d/g, '')[0] || '.';

Live thousand separators without losing the caret

dom intl caret-preservation
Advanced 8 steps
javascript
function initCharacterCounter(textarea, options = {}) {
  const maxLength = options.maxLength ?? 280;
  const warnThreshold = options.warnThreshold ?? 0.9;
 

A live character counter for textareas

dom closures accessibility
Intermediate 7 steps
javascript
function autoResizeTextarea(textarea, { maxHeight = Infinity } = {}) {
  const resize = () => {
    textarea.style.height = 'auto';
    const contentHeight = textarea.scrollHeight;

Auto-resizing a textarea to fit its content

dom event-listener cleanup
Intermediate 7 steps
typescript
export async function copyToClipboard(text: string): Promise<boolean> {
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(text);

Clipboard copy with a legacy fallback

clipboard feature-detection graceful-degradation
Intermediate 7 steps
javascript
class StarRating {
  constructor(container, { max = 5, value = 0, onChange } = {}) {
    this.container = container;
    this.max = max;

Building an accessible star-rating widget

dom event-handling accessibility
Intermediate 7 steps
typescript
type LazyImageOptions = {
  rootMargin?: string;
  loadedClass?: string;
};

Lazy-loading images with IntersectionObserver

intersectionobserver lazy-loading performance
Intermediate 7 steps
javascript
class InfiniteScroll {
  constructor(sentinel, { loadMore, root = null, rootMargin = '200px' } = {}) {
    this.sentinel = sentinel;
    this.loadMore = loadMore;

Infinite scroll with IntersectionObserver

intersectionobserver pagination async
Intermediate 10 steps
typescript
type ResizeCallback = (size: { width: number; height: number }) => void;
 
export function observeResize(callback: ResizeCallback, delay = 150) {
  let timeoutId: ReturnType<typeof setTimeout> | undefined;

Debouncing window resize in TypeScript

debounce closures event-listeners
Intermediate 6 steps
javascript
const ESCAPE_MAP = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',

Escaping HTML before injecting user content

xss-prevention escaping dom
Intermediate 6 steps
typescript
import { Directive, ElementRef, HostListener, Input, OnDestroy, OnInit } from '@angular/core';
 
@Directive({
  selector: '[appTrapFocus]',

Building a focus-trap directive in Angular

accessibility focus-management dom
Intermediate 9 steps
javascript
async function copyToClipboard(text) {
  if (navigator.clipboard && window.isSecureContext) {
    try {
      await navigator.clipboard.writeText(text);

Copying to the clipboard with a fallback

clipboard progressive-enhancement dom
Intermediate 8 steps
javascript
function initLazyLoad(root = document) {
  const images = root.querySelectorAll('img[data-src]');
 
  if (!('IntersectionObserver' in window)) {

How lazy image loading works

lazy-loading intersectionobserver progressive-enhancement
Intermediate 8 steps
javascript
function delegate(root, eventType, selector, handler) {
  const listener = (event) => {
    let node = event.target;
    while (node && node !== root) {

Event delegation with a clean teardown

event-delegation dom closures
Intermediate 8 steps