2010-05-05 2 views
5

Je souhaite insérer mes propres balises et scripts personnalisés autour du texte sélectionné. Quelque chose comme çaInsertion de balises personnalisées dans la sélection de l'utilisateur

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); 

Cela fonctionne dans les scénarios normaux, mais si je sélectionne un texte dans différents paragraphes de l'API extractContents validera le code HTML retourné et mettre des étiquettes supplémentaires pour la rendre valide HTML. Je veux le HTML exact qui a été sélectionné sans la validation supplémentaire que javascript a faite.

Y at-il un moyen de le faire? Je l'ai essayé de la façon mentionnée dans How can I highlight the text of the DOM Range object? mais la chose est que je veux des mises en évidence spécifiques à l'utilisateur, donc si A a ajouté un point culminant B ne devrait pas être capable de le voir. Pour cela, j'ai mon code backend prêt.

Répondre

0

Si vous ajoutez des balises au texte sélectionné appartenant à différents paragraphes, vous créez un code HTML incorrect.

Ceci est un exemple de code HTML invalide que vous pourriez générer.

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

Pour accomplir votre tâche, vous devez envelopper avec des étiquettes chaque texte dans chaque paragraphe de la sélection qui offre un code comme celui-ci.

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

Pour ce faire, vous devez itérer sur tous les noeuds sélectionnés et envelopper le texte sélectionné comme ceci:

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")); 
} 
Questions connexes