2010-05-05 10 views
5

Quiero insertar mis propias etiquetas y scripts personalizados en torno al texto seleccionado. Algo como estoInsertar etiquetas personalizadas en la selección de usuario

var range = window.getSelection().getRangeAt(0); 
var sel = window.getSelection(); 
range.setStart(sel.anchorNode, sel.anchorOffset); 
range.setEnd(sel.focusNode,sel.focusOffset); 

highlightSpan = document.createElement("abbr"); 
highlightSpan.setAttribute("style","background-color: yellow;"); 
highlightSpan.setAttribute("onmouseout","javascript:HideContentFade(\"deleteHighlight\");"); 
highlightSpan.setAttribute("onmouseover","javascript:ShowHighlighter(\"deleteHighlight\",\""+id_val+"\");"); 
highlightSpan.appendChild(range.extractContents()); 
range.insertNode(highlightSpan); 

Esto funciona en escenarios normales, pero si selecciono un texto en diferentes párrafos de la API extractContents validará el código HTML devuelto y poner etiquetas adicionales para que sea HTML válido. Quiero el HTML exacto que se seleccionó sin la validación adicional que hizo javascript.

¿Hay alguna manera de que esto se pueda hacer? Lo he intentado de la manera mencionada en How can I highlight the text of the DOM Range object? pero lo que quiero es resaltar aspectos específicos del usuario, por lo que si A ha agregado algo destacado, B no debería poder verlo. Para esto, tengo mi código de backend listo.

Respuesta

0

Si envuelve con etiquetas el texto seleccionado que pertenece a diferentes párrafos, crea código HTML no válido.

Este es un ejemplo de código HTML no válido que generaría.

<p>notselected <span>selected</p><p>selected</span> notselected</p> 

Con el fin de llevar a cabo su tarea, es necesario para envolver con las etiquetas de cada texto en cada párrafo de la selección que resulta en un código como este.

<p>notselected <span>selected</span></p><p><span>selected</span> notselected</p> 

Para lograr esto hay que iterar sobre todos los nodos seleccionados y envolver el texto seleccionado como esto:

function wrapSelection() { 
    var range, start, end, nodes, children; 

    range = window.getSelection().getRangeAt(0); 
    start = range.startContainer; 
    end = range.endContainer; 

    children = function (parent) { 
     var child, nodes; 

     nodes = []; 
     child = parent.firstChild; 

     while (child) { 
      nodes.push(child); 
      nodes = nodes.concat(children(child)); 
      child = child.nextSibling; 
     } 

     return nodes; 
    } 

    nodes = children(range.commonAncestorContainer); 
    nodes = nodes.filter(function (node) { 
     return node.nodeType === Node.TEXT_NODE; 
    }); 
    nodes = nodes.slice(nodes.indexOf(start) + 1, nodes.indexOf(end)); 
    nodes.forEach(function (node) { 
     wrap = window.document.createElement("span"); 
     node.parentNode.insertBefore(wrap, node); 
     wrap.appendChild(node); 
    }); 

    start = new Range(); 
    start.setStart(range.startContainer, range.startOffset); 
    start.setEnd(range.startContainer, range.startContainer.length); 
    start.surroundContents(window.document.createElement("span")); 

    end = new Range(); 
    end.setStart(range.endContainer, 0); 
    end.setEnd(range.endContainer, range.endOffset); 
    end.surroundContents(window.document.createElement("span")); 
} 
Cuestiones relacionadas