Clear Text Selection with JavaScript

Best to test the features you want directly:

var sel = window.getSelection ? window.getSelection() : document.selection;
if (sel) {
    if (sel.removeAllRanges) {
        sel.removeAllRanges();
    } else if (sel.empty) {
        sel.empty();
    }
}

if (window.getSelection) {
  if (window.getSelection().empty) {  // Chrome
    window.getSelection().empty();
  } else if (window.getSelection().removeAllRanges) {  // Firefox
    window.getSelection().removeAllRanges();
  }
} else if (document.selection) {  // IE?
  document.selection.empty();
}

Credit to Mr. Y.


2021 answer

  • removeAllRanges() is supported by most browsers, except Safari on macOS or iOS.

  • empty() is an alias for removeAllRanges() and supported by all browsers, including very old ones, with the exception of IE. This alias is defined in the specification, so should be safe to rely on.

Conclusion

Just use getSelection().empty(). There is no need for helper functions, nested ternary ifs, constructors, and whatnot Ninja banzai from the other answers. Perhaps needed ten years ago, but not any more.

If you really need IE support you can test for document.selection:

(window.getSelection ? window.getSelection() : document.selection).empty()

(not tested on IE)


State of De-selection Affairs 2014

I did some research of my own. Here's the function I wrote and am using these days:

(function deselect(){
  var selection = ('getSelection' in window)
    ? window.getSelection()
    : ('selection' in document)
      ? document.selection
      : null;
  if ('removeAllRanges' in selection) selection.removeAllRanges();
  else if ('empty' in selection) selection.empty();
})();

Basically, getSelection().removeAllRanges() is currently supported by all modern browsers (including IE9+). This is clearly the correct method moving forward.

Compatibility issues accounted for:

  • Old versions of Chrome and Safari used getSelection().empty()
  • IE8 and below used document.selection.empty()

Update

It's probably a good idea to wrap up this selection functionality for re-use.

function ScSelection(){
  var sel=this;
  var selection = sel.selection = 
    'getSelection' in window
      ? window.getSelection()
      : 'selection' in document
        ? document.selection
        : null;
  sel.deselect = function(){
    if ('removeAllRanges' in selection) selection.removeAllRanges();
    else if ('empty' in selection) selection.empty();
    return sel; // chainable :)
  };
  sel.getParentElement = function(){
    if ('anchorNode' in selection) return selection.anchorNode.parentElement;
    else return selection.createRange().parentElement();
  };
}

// use it
var sel = new ScSelection;
var $parentSection = $(sel.getParentElement()).closest('section');
sel.deselect();

I've made this a community wiki so that you people can add functionality to this, or update things as the standards evolve.