Las versiones recientes de los navegadores Firefox y WebKit tienen incorporado un método modify()
(vea también work-in-progress spec) del objeto Selection
para hacer esto. IE ha tenido una forma completamente diferente de hacerlo desde la versión 4. En cualquier caso, este método tiene la ventaja significativa de trabajar a través de los límites del elemento.
El siguiente ejemplo funciona en IE 4+, Firefox 4+ y Safari y Chrome en las versiones lanzadas en los últimos años. Opera aún no tiene soporte para el método modify()
de los objetos Selection
.
Actualización 20 de octubre de 2011
he reescrito que esto en realidad (en su mayoría) funciona en este momento (que no funcionaba correctamente en los navegadores no-IE antes, como se señaló en los comentarios). Desafortunadamente, la expansión de la selección es demasiado codiciosa en no-IE y amplía la selección a la siguiente palabra si ya se ha seleccionado una palabra completa, pero no puedo ver una manera fácil de evitar esto en este momento.
Actualización 11 de junio de 2012
ahora he actualizado esto con una mejora de this answer to a related question. Gracias a Matt M y a Fong-Wan Chau por esto.
Demostración en directo: http://jsfiddle.net/rrvw4/23/
Código:
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's trailing space(s),
// if necessary
while (/\s$/.test(textRange.text)) {
textRange.moveEnd("character", -1);
}
textRange.select();
}
}
}
Gracias por sonar.Esto parece una mejor respuesta. –
@James: una respuesta de solo rango junto con una cosa basada en 'TextRange' para IE más antiguo cubrirá más navegadores que mi respuesta, por lo que dependiendo de los requisitos del OP, la suya puede ser mejor. –
dos de ustedes son excelentes personas. gracias dos de ustedes, así que cambio la marca a tim, pero también gracias a james –