In recent versions of Firefox and WebKit browsers, there is a built-in modify() (see also work-in-progress spec ) method of the Selection object for this. IE had a completely different way of doing this since version 4. In any case, this method has a significant advantage in working on element borders.
The following example works in IE 4+, Firefox 4+, and Safari and Chrome in versions released over the last couple of years. Opera does not yet support the modify() method of Selection objects.
UPDATE October 20, 2011
I rewrote this actually (mostly) now (it did not work properly in browsers other than IE, as noted in the comments). Unfortunately, the selection extension is too greedy in non-IE and extends the selection to the next word if the whole word is already selected, but I donโt see an easy way at the moment.
UPDATE June 11, 2012
I updated this with an improvement from this answer to a related question . Thanks to Matt M and Fong-Wan Chau for this.
Live demo: http://jsfiddle.net/rrvw4/23/
the code:
function snapSelectionToWord() { var sel; // Check for existence of window.getSelection() and that it has a // modify() method. IE 9 has both selection APIs but no modify() method. if (window.getSelection && (sel = window.getSelection()).modify) { sel = window.getSelection(); if (!sel.isCollapsed) { // Detect if selection is backwards var range = document.createRange(); range.setStart(sel.anchorNode, sel.anchorOffset); range.setEnd(sel.focusNode, sel.focusOffset); var backwards = range.collapsed; range.detach(); // modify() works on the focus of the selection var endNode = sel.focusNode, endOffset = sel.focusOffset; sel.collapse(sel.anchorNode, sel.anchorOffset); var direction = []; if (backwards) { direction = ['backward', 'forward']; } else { direction = ['forward', 'backward']; } sel.modify("move", direction[0], "character"); sel.modify("move", direction[1], "word"); sel.extend(endNode, endOffset); sel.modify("extend", direction[1], "character"); sel.modify("extend", direction[0], "word"); } } else if ( (sel = document.selection) && sel.type != "Control") { var textRange = sel.createRange(); if (textRange.text) { textRange.expand("word"); // Move the end back to not include the word trailing space(s), // if necessary while (/\s$/.test(textRange.text)) { textRange.moveEnd("character", -1); } textRange.select(); } } }
source share