Inserting Custom Tags on User Selection
I want to insert my own custom tags and scripts around the selected text. Something like this
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;");
highl开发者_运维技巧ightSpan.setAttribute("onmouseout","javascript:HideContentFade(\"deleteHighlight\");");
highlightSpan.setAttribute("onmouseover","javascript:ShowHighlighter(\"deleteHighlight\",\""+id_val+"\");");
highlightSpan.appendChild(range.extractContents());
range.insertNode(highlightSpan);
This works in normal scenarios but if I select some text in different paragraphs the extractContents API will validate the HTML returned and put additional tags to make it valid HTML. I want the exact HTML that was selected without the additional validating that javascript did.
Is there any way this can be done? I have tried it the way mentioned in How can I highlight the text of the DOM Range object? but the thing is I want user specific highlights so if A has added some highlight B should not be able to see it. For this I have my backend code ready.
If you wrap with tags the selected text that belongs to different paragraphs, you create invalid HTML code.
This is an example of invalid HTML code that you would generate.
<p>notselected <span>selected</p><p>selected</span> notselected</p>
In order to accomplish your task, you need to wrap with tags each text in each paragraph of the selection resulting in a code like this.
<p>notselected <span>selected</span></p><p><span>selected</span> notselected</p>
To accomplish this you have to iterate over all nodes selected and wrap the selected text like this:
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"));
}
精彩评论