2011-03-07 6 views
8

Estoy tratando de resaltar una parte del texto en mi sitio web. Este texto resaltado se guardará para el usuario específico en una base de datos y, cuando se abra nuevamente, mostrará el texto resaltado anteriormente. Supuse que usaría javascript para resaltar el texto, pero parece que no puedo encontrar una manera de identificar dónde está la palabra que estoy resaltando.¿Cómo se identifica una palabra o una selección en todo el documento?

function getSelText() 
{ 
    var txt = ''; 
    if (window.getSelection) 
    { 
     txt = window.getSelection(); 
      } 
    else if (document.getSelection) 
    { 
     txt = document.getSelection(); 
      } 
    else if (document.selection) 
    { 
     txt = document.selection.createRange().text; 
      } 
    else return ""; 
    return txt; 
} 

que estoy usando para obtener la selección pero no puedo averiguar donde la selección está en el texto. La mayor molestia es cuando tengo duplicados dentro de la línea o el texto, así que si tuviera que usar la búsqueda, encontraría la primera instancia y no la que estaba buscando.

Entonces, la pregunta es: ¿cómo se identifica una palabra o una selección en todo el documento?

Respuesta

4

Puede usar mi biblioteca Rangy y su selection serialization module para esto. El núcleo de Rangy proporciona una API consistente de selección y rango para todos los navegadores y el módulo de serialización se basa en esto al convertir cada límite de selección en una ruta a través del documento. Consulte la documentación vinculada para más detalles.

1

createRange crea un objeto textRange. Cuenta con todo tipo de información útil:

  var range = document.selection.createRange(); 

      var left = range.boundingLeft; 
      var top = range.boundingTop; 
+0

Eso no funcionará realmente ya que no tengo ningún área de texto de la que hablar, simplemente tengo un documento que se lee de la base de datos y se muestra. – vman

3

Esto ciertamente no es una tarea trivial, ya que se enfrenta a los dos grandes problemas de localizar el texto en el documento actual, y luego ser capaz de encontrarlo de nuevo en una carga de página posterior. El problema se complica aún más si el contenido de su página está sujeto a cambios, ya que ni siquiera puede confiar en que la posición relativa del texto permanezca igual.

Es posible que desee considerar si es o no es el mejor enfoque para lo que estamos tratando de lograr dado el esfuerzo necesario, pero aquí hay algo que podría empezar en la dirección correcta:

function getSelection() { 
    var selection, position; 

    if (window.getSelection) { 
     selection = window.getSelection(); 

     if (selection && !selection.isCollapsed) { 
      position = { 
       'offset': selection.anchorOffset, 
       'length': selection.toString().length, 
       // We're assuming this will be a text node 
       'node': selection.anchorNode.parentNode 
      }; 
     } 
    } else if (document.selection) { 
     selection = document.selection.createRange(); 

     if (selection && selection.text.length) { 
      var text = selection.parentElement().innerText, 
       range = document.body.createTextRange(), 
       last = 0, index = -1; 

      range.moveToElementText(selection.parentElement()); 

      // Figure out which instance of the selected text in the overall 
      // text is the correct one by walking through the occurrences 
      while ((index = text.indexOf(selection.text, ++index)) !== -1) { 
       range.moveStart('character', index - last); 
       last = index; 

       if (selection.offsetLeft == range.offsetLeft && selection.offsetTop == range.offsetTop) { 
        break; 
       } 
      } 

      position = { 
       'offset': index, 
       'length': selection.text.length, 
       'node': selection.parentElement() 
      }; 
     } 
    } 

    return position; 
} 

así como un método para seleccionar el texto de nuevo:

function setSelection(position) { 
    if (!position || !position.node) { 
     return; 
    } 

    var selection, range, element; 

    if (document.createRange) { 
     element = position.node.childNodes[0]; 
     range = document.createRange(); 
     range.setStart(element, position.offset); 
     range.setEnd(element, position.offset + position.length); 
     selection = window.getSelection(); 
     selection.removeAllRanges(); 
     selection.addRange(range); 
    } else if (document.body.createTextRange) { 
     range = document.body.createTextRange(); 
     range.moveToElementText(position.node); 
     range.collapse(true); 
     range.move('character', position.offset); 
     range.moveEnd('character', position.length); 
     range.select(); 
    } 
} 

Este código hace la suposición más bien ingenua de que el texto seleccionado todo reside en el mismo elemento de DOM. Hay muchas posibilidades de que si un usuario está seleccionando texto arbitrario, este no sea el caso.

Teniendo en cuenta que las cuentas de este Selection object con los anchorNode y focusNode propiedades, que podrían tratar de solucionar este problema, aunque se trata de la TextRange object en Internet Explorer podría llegar a ser un poco más problemático.

También existe el problema de cómo realizar un seguimiento del valor position.node entre las solicitudes de página. En mi jsFiddle sample, he usado una versión ligeramente modificada de selector-generating jQuery function para generar una cadena de selector que se puede guardar y usar para volver a seleccionar el nodo correcto más adelante. Tenga en cuenta que el proceso es relativamente trivial, por lo que podría hacerlo fácilmente sin jQuery –, simplemente pasó a ahorrar un poco de esfuerzo en este caso.

Por supuesto, si cambia el DOM entre visitas, este enfoque probablemente sea bastante inestable. Si no lo eres, siento que probablemente sea una de las opciones más confiables.

+1

Este es un enfoque similar (pero menos realizado por completo) para el módulo Serializador en mi biblioteca Rangy: http://code.google.com/p/rangy/wiki/SerializerModule –

+0

@TimDown Oh wow, estoy un poco avergonzado No pensé en Rangy al escribir la respuesta dadas mis experiencias pasadas positivas con ella. Gracias por el enlace. –

+0

Gracias a un grupo la biblioteca rangy hizo el truco. – vman

Cuestiones relacionadas