我正在使用mouseup事件来触发一个突出显示文本的函数,并用一个span来覆盖突出显示的文本(来自堆栈溢出的函数):
function highlightText(e) {
var t = window.getSelection().toString();
if (t) {
$("#mySpan").remove();
var range = window.getSelection().getRangeAt(0);
newNode = document.createElement("span");
newNode.id = 'mySpan';
range.surroundContents(newNode);
}
}
我遇到的主要问题是,只要包含surroundContents
,文本只会突出显示约20%的突出显示尝试(否则突出显示会立即消失)。我尝试添加一个setTimeout,而不是为1s调用surroundContent。我也尝试删除remove()语句,但仍然没有用。
关于为什么会发生这种情况的任何想法?
答案 0 :(得分:2)
我在Android上遇到了与Chromium相同的问题。在某些特定情况下,range.surroundContents(newNode)
的调用会导致页面重新加载等非常奇怪的行为。检查the documentation of the function后:
这种方法几乎等同于 newNode.appendChild(range.extractContents()); range.insertNode(newNode)。周围后,边界点 范围包括newNode。
所以显而易见的是采用另一种方式突出显示文本。我找到了mark.js库,它完全按我想要的那样做,没有那令人讨厌的副作用。 (这是一个JSFiddle sample,显示它是如何用来突出显示选择的)。不同之处在于图书馆未使用range.surroundContents(newNode)
或newNode.appendChild
,而是使用node.replaceChild
。
基于此,这是我遇到的问题的解决方案,我认为它也适用于你的案例。
function surroundRangeWithSpan(range) {
var span = document.createElement('span');
// The text is within the same node (no other html elements inside of it)
if (range.startContainer.isEqualNode(range.endContainer) && range.startContainer.childNodes.length == 0) {
// Here you customise your <span> element
customSurroundContents(range, span);
} else {
// Here you have to break the selection down
}
return span;
}
function customSurroundContents(range, span) {
var node = range.commonAncestorContainer;
var startNode = node.splitText(range.startOffset);
var ret = startNode.splitText(range.toString().length);
span.textContent = startNode.textContent;
startNode.parentNode.replaceChild(span, startNode);
}
您将window.getSelection().getRangeAt(0)
传递给该函数。
答案 1 :(得分:1)
失败的可能原因是所选文本仅包含非文本节点的开头或结尾,而不是两者都包含。
因此,如果仅运行该代码,则在下面选择“This is Bo”将失败(并抛出异常),因为它也不会捕获选择中的结束标记:
This is <em>bold</em>
结束于:
This is <em>bo
参考:https://developer.mozilla.org/en-US/docs/Web/API/Range/surroundContents