Obtener el texto resaltado / seleccionado

351

¿Es posible obtener el texto resaltado en un párrafo de un sitio web, por ejemplo, usando jQuery?

Dan
fuente
2
Aquí hay una solución de trabajo dipaksblogonline.blogspot.in/2014/11/…
Dipak
JavaScript simple funcionó para mí. document.getSelection (). anchorNode.data.substr (document.getSelection (). anchorOffset, document.getSelection (). focusOffset-document.getSelection (). anchorOffset)
Rohit Verma
@RohitVerma: Eso solo funcionará en el caso simple de una selección contenida dentro de un solo nodo de texto, que de ninguna manera se garantiza que sea el caso.
Tim Down
@Dipak ¿Cómo replicas la funcionalidad para compartir en redes sociales del blog al que haces referencia en tu publicación? En lugar de simplemente devolver la cadena seleccionada, estoy tratando de completar esa variable en un enlace de Twitter.

Respuestas:

481

Obtener el texto que el usuario ha seleccionado es relativamente simple. No se obtiene ningún beneficio al involucrar a jQuery ya que no necesita nada más que los objetos windowy document.

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().toString();
    } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
    }
    return text;
}

Si está interesado en una implementación que también se ocupe de selecciones <textarea>y <input>elementos de texto, puede usar lo siguiente. Como ahora es 2016, estoy omitiendo el código requerido para IE <= 8, pero he publicado cosas para eso en muchos lugares en SO.

function getSelectionText() {
    var text = "";
    var activeEl = document.activeElement;
    var activeElTagName = activeEl ? activeEl.tagName.toLowerCase() : null;
    if (
      (activeElTagName == "textarea") || (activeElTagName == "input" &&
      /^(?:text|search|password|tel|url)$/i.test(activeEl.type)) &&
      (typeof activeEl.selectionStart == "number")
    ) {
        text = activeEl.value.slice(activeEl.selectionStart, activeEl.selectionEnd);
    } else if (window.getSelection) {
        text = window.getSelection().toString();
    }
    return text;
}

document.onmouseup = document.onkeyup = document.onselectionchange = function() {
  document.getElementById("sel").value = getSelectionText();
};
Selection:
<br>
<textarea id="sel" rows="3" cols="50"></textarea>
<p>Please select some text.</p>
<input value="Some text in a text input">
<br>
<input type="search" value="Some text in a search input">
<br>
<input type="tel" value="4872349749823">
<br>
<textarea>Some text in a textarea</textarea>

Tim Down
fuente
99
¿Para qué más sirve {} -fork? ¿De qué trata "Control"?
Dan
29
@Dan: Lo siento, me perdí esta pregunta (no creo que SO me haya alertado). La segunda rama es para IE <= 8 (IE 9 implementa window.getSelection()). La document.selection.typeverificación prueba que la selección es una selección de texto en lugar de una selección de control. En IE, una selección de control es una selección dentro de un elemento editable que contiene uno o más elementos (como imágenes y controles de formulario) con contornos y controladores de tamaño. Si llama .createRange()a una selección de este tipo, obtiene una en ControlRangelugar de una TextRangey ControlRangeno tiene ninguna textpropiedad.
Tim Down
2
@TimDown Es muy delgado decir "jQuery no tiene X", porque, por supuesto, con el complemento correcto, puede hacer cualquier cosa que pueda hacer en el navegador con javascript. En este caso, tenemos jquery.selection ( madapaja.github.io/jquery.selection ). Es igualmente incorrecto decir "ni debería". Llegué aquí porque estaba buscando exactamente esto. Tengo un caso de uso, y jQuery es la solución correcta.
Auspex
8
@Auspex: Entiendo tu punto de vista pero no estoy de acuerdo. Un complemento jQuery es una biblioteca que depende de jQuery; no es en sí mismo jQuery. En el caso del manejo de selección, jQuery en sí mismo no proporciona precisamente nada (que es como debería ser porque el manejo de selección no es para lo que es jQuery), por lo que cualquier solución que use jQuery lo está usando de manera incidental.
Tim Down
1
@ Dennis98: no estoy molesto ni ofendido de forma remota :) La verificación de los tipos de entrada se debe a que recibe advertencias en la consola en Chrome si intenta acceder selectionStarto selectionEnden un <input>tipo de elemento (como "número") que no admitirlo (ver jsfiddle.net/6zoposby/2 , por ejemplo). Dejé el cheque por la existencia de selectionStartmodo que el código no se rompa en IE <= 8. Admito que el cheque para activeElementprobablemente sea excesivo ahora. Lo uso sliceporque es más poderoso (aunque eso no es útil aquí) y un poco más corto para escribir que substring.
Tim Down
111

Obtenga el texto resaltado de esta manera:

window.getSelection().toString()

y, por supuesto, un tratamiento especial para, por ejemplo:

document.selection.createRange().htmlText
ParPar
fuente
2
Para IE> = 10 "el document.selection soporte se eliminó en IE10 y se reemplazó con window.getSelection ". Fuente: connect.microsoft.com/IE/feedback/details/795325/…
usuario2314737
Esto fallará bajo múltiples condiciones en varios navegadores (por ejemplo, Firefox).
Makyen
11

Esta solución funciona si está usando Chrome (no puede verificar otros navegadores) y si el texto se encuentra en el mismo elemento DOM:

window.getSelection().anchorNode.textContent.substring(
  window.getSelection().extentOffset, 
  window.getSelection().anchorOffset)
Andrew Kennedy
fuente