我正在使用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()语句,但仍然没有好处.
有关为何发生这种情况的任何想法?
解决方法
我在Android上遇到了与Chromium相同的问题.在某些特定情况下,调用range.surroundContents(newNode)会导致页面重新加载等非常奇怪的行为.检查
the documentation of the function后:
This method is nearly equivalent to
newNode.appendChild(range.extractContents());
range.insertNode(newNode). After surrounding,the boundary points of
the range include 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)传递给函数.