# Double Click to Select All Code

**Date:** 2014-04-22  
**Author:** Kees C. Bakker  
**Categories:** JavaScript, jQuery  
**Original:** https://keestalkstech.com/click-to-select-all-on-the-pre-element/

![Child with a mac book mouse clicking that mouse with two fingers.](https://keestalkstech.com/wp-content/uploads/2014/04/charles-deluvio-rA83MmTX46U-unsplash-scaled.jpg)

---

When you want to display code, you are probably using `PRE` elements. The fact that these elements can contain markup makes them perfectly suited for syntax highlighting. Some plugins make it easier to copy the code using a button. Google Prettify has no such option. Let's see if we can make copying easier by providing a "double click to select all"-feature to our pre fields.

## Getting a parent - the native way

In the past, I've used jQuery to do the heavy lifting in JavaScript. As browsers got better support for standard JavaScript API's this is often no longer needed. I'm a big fan of the `closest` function, so let's implement it in native JavaScript:

```js
function getClosest(el, tagName) {
  tagName = tagName && tagName.toUpperCase();

  if (!tagName || !el)
    return null;

  do
    if (el.nodeName === tagName)
      return el;
  while (el = el.parentNode);

  return null;
}
```

## Select All on Double Click

Let's use `Range` and `document.getSelection` to select all the text of the `PRE` element. On my site all elements contain `CODE` and `SPAN` elements that are needed for highlighting, so we use our `getClosest` function to find the `PRE`-parent:

```js
document.addEventListener('dblclick', e => {
  let pre = getClosest(e.target, "PRE");
  if (pre) {
    let range = new Range();
    range.setStart(pre, 0);
    range.setEnd(pre, 1);
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(range);
  }
});
```

The `Range` API has [partial support in IE11](https://developer.mozilla.org/en-US/docs/Web/API/Range#Browser_compatibility).

## Need something smaller?

The code above is pretty small -- only 504 bytes. But if you are really set on something smaller, you could minify it further to 327 bytes by applying [UglifyJS](https://skalman.github.io/UglifyJS-online/) on it:

```js
!function(){let e=document;e.addEventListener("dblclick",t=>{let n=function(e,t){if(!(t=t&&t.toUpperCase())||!e)return null;do{if(e.nodeName===t)return e}while(e=e.parentNode);return null}(t.target,"PRE");if(n){let t=new Range;t.setStart(n,0),t.setEnd(n,1),e.getSelection().removeAllRanges(),e.getSelection().addRange(t)}})}();
```

It gets somewhat smaller, but it does not get more readable! 😀 Check how minification got rit of the `getClosest` method and just evaluates the result. Pretty neat!

## Styling the selection

You might want to add some extra styling to the selection using CSS. The following CSS will add a gray background to the selection and keep the colors produced by the syntax highlighting:

```css
pre::selection,
pre *::selection {
    background-color: #999;
}

pre::selection,
pre *::-moz-selection {
    background-color: #999;
}
```

## Further reading

- In-depth study of `Range` by [JavaScript.info: Selection and Range](https://javascript.info/selection-range)
- [CSS Tricks: Overriding The Default Text Selection Color With CSS](https://css-tricks.com/overriding-the-default-text-selection-color-with-css/)

## Improvements

2020-07-21: removed the jQuery dependency of the code and introduced the modern `Range` API.
2020-04-22: the original article was written. [It can be found here in the Internet Archive](https://web.archive.org/web/20200721063841/https://keestalkstech.com/2014/04/click-to-select-all-on-the-pre-element/) or [here](https://web.archive.org/web/20200721063850/http://web.archive.org/screenshot/https://keestalkstech.com/2014/04/click-to-select-all-on-the-pre-element/).
