Troubleshooting & How-Tos 📡 🔍 Web Development

Select All of a Code Sample Using Minimal JS

I’ve got a lot of code samples on here, plus the bookmarklets collection. It’s not hard so select the whole block with a mouse, but it’s not exactly easy either. (You can triple-click to select a paragraph, but code samples are rarely paragraphs.)

You can do this with various JavaScript frameworks, but one of my goals on this site is to keep the bandwidth and processing minimal. One HTML file per article, one shared CSS file. I figured I should be able to do this with vanilla JavaScript now.

Turns out it’s pretty simple, and if you only want to use it with mouse clicks and touch taps, it’s only 4 lines of JavaScript (plus closing braces/parentheses). Here I’m setting it on all code elements that are inside pre blocks.

const codeSamples = document.querySelectorAll("pre code");
codeSamples.forEach( (sample) => {
  sample.addEventListener("click", (e) => {
    window.getSelection().selectAllChildren(e.target);
  });
});

That doesn’t take care of keyboard users, though. You can add a “keypress” event, but <code> isn’t normally focusable by tab. Fortunately it’s easy enough to add an element to the tab order in JavaScript (zero means let the browser decide where to put it), and we already have it looping through the nodes we want to modify.

  sample.setAttribute("tabindex",0);
  sample.addEventListener("keypress", (e) => {
    window.getSelection().selectAllChildren(e.target);
  });

So the full code fragment is 7 lines of actual code, plus closing braces and comments.

// Select the entire contents of a code sample.
const codeSamples = document.querySelectorAll("pre code");
codeSamples.forEach( (sample) => {
  
  // Select everything when clicked.
  sample.addEventListener("click", (e) => {
    window.getSelection().selectAllChildren(e.target);
  });
  
  // Add to tab list and select when a key is pressed.
  sample.setAttribute("tabindex",0);
  sample.addEventListener("keypress", (e) => {
    window.getSelection().selectAllChildren(e.target);
  });
  
});

This approach works in modern Chromium, WebKit and Gecko-based web browsers. I haven’t tested how it interacts with screen readers or other accessibility features yet.