2011-03-03 10 views
25

Actualmente un me estoy el texto seleccionado en el navegador haciendo esto:ser elegida la posición del texto

window.getSelection(); 

ahora tengo que mostrar un texto de ayuda por encima de ese texto al pulsar una tecla personalizable (tenga en cuenta que el ratón podía ya no estar sobre el texto), entonces para hacer eso necesito la posición absoluta de ese texto seleccionado.

¿Hay una manera de hacer eso, tal vez envolviendo ese texto dentro de una etiqueta y luego conseguir las compensaciones?

¿Alguna idea?


PD: tienen que trabajar de cromo, no para todos los navegadores.

PS2: Lo siento por mi mierda Inglés.

+0

duplicado posible de [Cómo puedo posicionar un elemento de lado de usuario selección de texto?] (https://stackoverflow.com/questions/1589721/how-can-i-position-an-element-next-to-user-text-selection) – Liam

Respuesta

11

La forma más fácil es insertar un elemento marcador temporal al principio o al final de la selección y obtener su posición. He demostrado cómo hacer esto antes de desbordamiento de pila: How can I position an element next to user text selection?

+0

Si este es un duplicado de esa pregunta, entonces shouldn ¿Vota por cerrar? ¿No agregas una respuesta que apunta a otra respuesta? – Liam

+1

@Liam: No estoy seguro; las preguntas no son idénticas, pero la técnica necesaria para responderlas es la misma. No puedo negar que estaba en mi fase máxima de búsqueda de rep a la hora de responder. –

38
s = window.getSelection(); 

Devuelve una selección. Así que intente

s = window.getSelection(); 
oRange = s.getRangeAt(0); //get the text range 
oRect = oRange.getBoundingClientRect(); 

oRect será el rectángulo delimitador en las coordenadas del cliente (fijo).

+0

El método 'getBoundingClientRect()' de Range no es universalmente compatible, desafortunadamente, aunque está llegando allí. No creo que IE9 lo tenga, por ejemplo. –

+5

La pregunta solo está relacionada con Chrome. Esto funciona en Chrome y FF. – Jerinaw

+3

'oRange' ... Veo lo que hizo allí :) – volter9

0

Antes de utilizar getBoundingClientRect, lo que necesita saber this note:

CSSOM borrador de trabajo especifica que devuelve un ClientRect para cada cuadro de la frontera

Y por esta 'estándar':

Para un elemento en línea, las dos definiciones son las mismas. Pero para un elemento de bloque, Mozilla solo devolverá un único rectángulo.

Así que si cualquiera que lea este post quiere una solución general para las posiciones más precisas y diseños de textos seleccionados, sugiero los siguientes enfoques:

Opción 1: Encuentra exacta de inicio y y punto de textos que termina por inserting invisible elements. Luego calcule los rectángulos de línea seleccionados con la altura de línea calculada extraída y el ancho del contenedor. API en uso: window.getComputedStyle.

  • Pro: el resultado sería el más preciso para cada línea de texto.
  • Con: 1) Si la selección es a través de varios nodos con diferentes alturas de línea y anchuras, el algoritmo se vuelve compleja. 2) Y debe implementar el algoritmo de cálculo, que consume demasiado tiempo al implementar una característica simple.

Opción 2: envolver cada texto con un elemento en línea cuidadosamente labrada, extrayendo diseño de cada cuadro, y combinar los resultados en las líneas.

  • Pro: Funciona para todas las selecciones continuas (que básicamente significa todos los casos en las implementaciones actuales del navegador principal). Buena precisión para cada línea de textos.
  • Con: 1) Su resultado es un poco inexacto en algunos casos, ya que agrega anchos de error de kerning. 2) Es lento en una gran selección de textos.

Para la opción 2, rangeblock es una implementación existente con una API sencilla que le da la disposición de la absolución de cada línea de texto:

let block = rangeblock.extractSelectedBlock(window, document); 
console.info("Text layout: " + JSON.stringify(block.dimensions)); 
// output: Text layout: {Left: 100, Top: 90, Width: 200, Height: 50} 
Cuestiones relacionadas