2012-05-24 10 views
6

Necesito obtener el área seleccionada por el usuario de un área de texto y luego insertar las etiquetas <a> a su alrededor.¿Poner etiquetas redondas para resaltar el texto del usuario?

Lo utilizo para obtener el área seleccionada por el usuario:

var textComponent = document.getElementById('article'); 
var selectedText; 

if (document.selection != undefined) 
{ 
    textComponent.focus(); 
    var sel = document.selection.createRange(); 
    selectedText = sel.text; 
} 

// Mozilla version 
else if (textComponent.selectionStart != undefined) 
{ 
    var startPos = textComponent.selectionStart; 
    var endPos = textComponent.selectionEnd; 
    selectedText = textComponent.value.substring(startPos, endPos) 
} 

Ahora, sé que puedo hacer una búsqueda de cadena para el texto seleccionado por el usuario e insertar un tag alrededor de ella, pero lo que pasa si el usuario ha seleccionado el texto aparece dos veces en el texto, por ejemplo.

Hola, adiós.

Si el usuario resalta el segundo 'usted' para el enlace que desea, seguramente una cadena de reemplazo pondría una etiqueta alrededor de cada instancia de 'usted'.

¿Cuál es la mejor manera de hacerlo?

+0

Espero que una cadena de reemplazo le daría la opción de "reemplazar todo" o "reemplazar la primera aparición". Si usa "primera aparición" y puede comenzar en el punto de inicio de selección, ¿podría ser suficiente? – pjmorse

+0

manteniendo una variable 'lastFocusedElement' puede ayudar. Encuentra texto en ese elemento en particular. – Jashwant

Respuesta

5

Se podía usar mi jQuery plug-in para esto (demo):

$("#article").surroundSelectedText('<a href="foo.html">', "</a>"); 

Como alternativa puede usar la función getInputSelection() que he publicado en el desbordamiento de la pila un par de veces para obtener los índices de inicio de la selección y el carácter de fin de todos los principales navegadores y luego hacer sustitución de cadenas en value del área de texto:

var sel = getInputSelection(textComponent); 
var val = textComponent.value; 
textComponent.value = val.slice(0, sel.start) + 
         '<a href="foo.html">' + 
         val.slice(sel.start, sel.end) + 
         "</a>" + 
         val.slice(sel.end); 
+0

¿es esta la última versión que debe incluirse (+1 de todos modos)? https://code.google.com/p/rangyinputs/downloads/detail?name=textinputs_jquery.js&can=2&q= – dynamic

+0

@llnk: Sí. Hay una copia en GitHub por el sitio del complemento de jQuery, pero no he necesitado actualizarlo. –

+0

Lo estoy probando y está funcionando bastante bien. Pero creo que carece de una función: cuando agrega las etiquetas una segunda vez, no elimina la etiqueta agregada anterior. Inserta dos veces esa etiqueta. ¿Sería posible agregar este comportamiento cuando lo usa dos veces con las mismas etiquetas? – dynamic

2

por qué capturar el texto seleccionado en absoluto? Lo que realmente quieres es que las posiciones de inicio/final caigan en las etiquetas.

var textComponent = document.getElementById('article'); 
var selectedText; 
var startPos; 
var endPos; 

// the easy way 
if (textComponent.selectionStart != undefined) 
{ 
    startPos = textComponent.selectionStart; 
    endPos = textComponent.selectionEnd; 
} 
// the hard way 
else if (document.selection != undefined) 
{ 
    textComponent.focus(); 
    var sel = document.selection.createRange(); 
    var range = document.selection.createRange(); 
    var stored_range = range.duplicate(); 
    stored_range.moveToElementText(textComponent); 
    stored_range.setEndPoint('EndToEnd', range); 
    startPos = stored_range.text.length - range.text.length; 
    endPos = startPos + range.text.length; 
} 

// add in tags at startPos and endPos 
var val = textComponent.value; 
textComponent.value = val.substring(0, startPos) + "<a>" + val.substring(startPos, endPos) + "</a>" + val.substring(endPos); 

código de IE modificado de this reference.

EDITAR: Anotar el comentario de Tim Down sobre nuevas líneas. Además, probablemente use su solución, porque es mejor.

+0

Yo preferiría 'selectionStart' y' selectionEnd' sobre el enfoque TextRange en buscadores que admitan ambos (como IE> = 9). Además, este código no detectará correctamente las selecciones que comienzan o terminan con líneas vacías en IE: consulte http://jsfiddle.net/Lq5aP/1/. Finalmente, hay un error tipográfico en la rama IE: debe ser 'endPos = startPos + range.text.length;'. –

+0

Se corrigió el código y se recomendaba su solución, ya que este es un dominio en el que obviamente ha reflexionado mucho. – apsillers

+0

Gracias, es muy amable de tu parte. –

Cuestiones relacionadas