2010-08-30 20 views
9

Quiero poder hacer doble clic para seleccionar texto en un div, que luego desencadena una función de JavaScript que inserta algo de HTML después del texto seleccionado, muy parecido a la función 'editar/responder' en Google Wave.Insertar HTML después de una selección

Ya he establecido cómo activar una función haciendo doble clic, está ubicando la selección y luego insertando HTML después de que ese es el problema.

Respuesta

1

window.getSelection() obtendrá el texto seleccionado (Documentation). Puede usar jQuery.after() (Documentation) para insertar html nuevo después de un elemento.

En la llamada de función de texto seleccionada, deberá recorrer todos los elementos DOM verificando su x & y posiciones en la posición actual del cursor - obtenga el elemento más cercano e inserte después o use la función .elementFromPoint (x, y) (Documentation)

Esta es la mejor manera en que actualmente puedo pensar. No es perfecto, pero es un lugar para comenzar.

+0

¿Cómo se obtiene las coordenadas en el primer lugar? Porque 'window.getSelection()' no devuelve ninguna x, y coordenadas – Abdel

0

No sé si es posible, pero pensé en una solución parcial.

En su evento de doble clic puede obtener el event object and access the propertytarget.

Teniendo el elemento de destino, you can get the selected text.

Ahora obtenga el elemento objetivo html y encuentre el índice del texto seleccionado y su longitud, inyecte su html en la posición index + length.

Creo que ya vio el problema, podría coincidir con el texto en varios lugares. Para resolverlo, es posible que deba encontrar la posición del cursor y comparar con el elemento, no sé cómo hacerlo ...

Espero que pueda ayudar un poco.

12

La siguiente función se inserte un nodo DOM (elemento o nodo de texto) al final de la selección en todos los principales navegadores (tenga en cuenta que Firefox ahora permite múltiples selecciones por defecto, la siguiente usa sólo la primera selección):

function insertNodeAfterSelection(node) { 
    var sel, range, html; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = sel.getRangeAt(0); 
      range.collapse(false); 
      range.insertNode(node); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     range = document.selection.createRange(); 
     range.collapse(false); 
     html = (node.nodeType == 3) ? node.data : node.outerHTML; 
     range.pasteHTML(html); 
    } 
} 

Si prefiere insertar una cadena HTML:

function insertHtmlAfterSelection(html) { 
    var sel, range, node; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = window.getSelection().getRangeAt(0); 
      range.collapse(false); 

      // Range.createContextualFragment() would be useful here but is 
      // non-standard and not supported in all browsers (IE9, for one) 
      var el = document.createElement("div"); 
      el.innerHTML = html; 
      var frag = document.createDocumentFragment(), node, lastNode; 
      while ((node = el.firstChild)) { 
       lastNode = frag.appendChild(node); 
      } 
      range.insertNode(frag); 
     } 
    } else if (document.selection && document.selection.createRange) { 
     range = document.selection.createRange(); 
     range.collapse(false); 
     range.pasteHTML(html); 
    } 
} 

actualización 18 de enero de 2012

Finalmente, aquí hay una versión que inserta HTML y conserva la selección (es decir amplía la selección para incluir el contenido seleccionado originalmente más el contenido insertado).

Demostración en directo: http://jsfiddle.net/timdown/JPb75/1/

Código:

function insertHtmlAfterSelection(html) { 
    var sel, range, expandedSelRange, node; 
    if (window.getSelection) { 
     sel = window.getSelection(); 
     if (sel.getRangeAt && sel.rangeCount) { 
      range = window.getSelection().getRangeAt(0); 
      expandedSelRange = range.cloneRange(); 
      range.collapse(false); 

      // Range.createContextualFragment() would be useful here but is 
      // non-standard and not supported in all browsers (IE9, for one) 
      var el = document.createElement("div"); 
      el.innerHTML = html; 
      var frag = document.createDocumentFragment(), node, lastNode; 
      while ((node = el.firstChild)) { 
       lastNode = frag.appendChild(node); 
      } 
      range.insertNode(frag); 

      // Preserve the selection 
      if (lastNode) { 
       expandedSelRange.setEndAfter(lastNode); 
       sel.removeAllRanges(); 
       sel.addRange(expandedSelRange); 
      } 
     } 
    } else if (document.selection && document.selection.createRange) { 
     range = document.selection.createRange(); 
     expandedSelRange = range.duplicate(); 
     range.collapse(false); 
     range.pasteHTML(html); 
     expandedSelRange.setEndPoint("EndToEnd", range); 
     expandedSelRange.select(); 
    } 
} 
+0

Gracias. Voy a intentar esto. – Lucy

+0

¿es posible mantener la selección después de insertar el html? Ahora mismo inserto el html pero luego la selección se pierde. – Towa

+0

@Towa: ¿Conservar cómo?¿Quiere decir que la selectio se expande para incluir el contenido insertado? Asumiré eso y publicaré una versión revisada ... –

Cuestiones relacionadas