Development

JavaScript that improves a working page

Start with working HTML. Add controls and gentle transitions while keeping the article available if the script fails.

4 min read
  • JavaScript
  • HTML
  • accessibility
  • progressive enhancement

A link to an article should open the article. HTML is enough for that. JavaScript can add a slider, hide the header on scroll or help open the menu. If that code fails, people should still be able to reach the material.

This approach is called progressive enhancement: build a working foundation, then add conveniences. It helps when the network is slow, scripts are disabled or one component fails. Search engines and other automated systems also receive the content directly in the server response.

Start with clear HTML

Use a link with a real URL for navigation. Use a button for an action on the current page. Do not replace them with div elements that have click handlers.

<a href="/materials/?article=architecture/reliable-integrations">
  Reliable integrations
</a>
<button type="button" hidden data-next>
  Next material
</button>

The link works immediately. Show the control button after the slider has been set up successfully. This avoids displaying a control that does nothing. Its label should describe the action. An arrow alone, without an accessible name, does not explain the action to every user.

Render the card headings, short descriptions and URLs before the script runs. If additional slides are hidden, make all materials available through an ordinary list or catalogue. Do not load an article's main text only after JavaScript starts.

Use modern syntax where it helps

Declare a variable with const when you do not intend to assign another value to it. Use let for changing state, such as the current slide number. const does not make an object's contents immutable: its properties can still change.

Load a file with defer if it needs to run after the HTML has been parsed. You can use modules for several related files. Modules make dependencies explicit; a small site does not necessarily need a complex build process.

<script src="/assets/ui.js" defer></script>

A language-standard number does not prove that a browser supports a feature. Choose features available in the required browsers and check the result. Simple navigation usually needs only established JavaScript and DOM features.

Check that the component exists

A shared script runs on different pages. One page may contain a slider, while another contains only an article. Initialise each component separately:

function initSlider() {
  const slider = document.querySelector('[data-slider]');
  if (!slider) return;

  const next = slider.querySelector('[data-next]');
  if (!next) return;

  // Attach the handler, then show the control.
  next.addEventListener('click', showNextSlide);
  next.hidden = false;
}

In this example, showNextSlide is a slide-switching function that you need to define in the component. The snippet is not a complete slider. It shows the sequence: find the elements, attach the action, show the button. A missing slider should not stop setup of the menu or other independent elements.

Preserve reading and keyboard access

A slider can switch when the reader asks it to. Automatic advancement needs more work: pause controls, focus handling and respect for reduced-motion preferences. Manual switching is usually enough for a selection of articles.

A hidden header should reappear when someone moves focus to the menu. After the user closes the mobile menu with Escape, return focus to its opening control. Check the path with Tab, Shift+Tab and Enter as well as with a mouse.

Avoid unnecessary layout calculations during scrolling. Group updates in requestAnimationFrame; the handler should not start an endless animation. Disable decorative movement when prefers-reduced-motion is set.

Use textContent to change an ordinary label. Do not insert an external string through innerHTML: the browser treats it as markup. If you need a new element, create it through the DOM and set validated attributes.

Check what the reader sees

Check the file's syntax with node --check assets/ui.js. This command does not run a browser or check the buttons. Then open the page, press F12 and select the Console tab. Actions should not produce site errors.

Disable JavaScript and reopen the home page and an article. Check links, text and access to all materials. On a narrow screen, scroll the page, open the menu and switch a slide. A working foundation and clear controls matter more than the number of language features used.

Official sources

Shall we discuss
your project?

Describe the problem and the result you need. I will explain where I can help.

One-off tasks: a contract with a self-employed provider under Russia’s professional income tax regime (NPD). Commercial projects: a contract with a Russian limited liability company (OOO). Terms and provider details are agreed before work starts.