javascript - 使用 JavaScript 突出显示文本范围

标签 javascript selection textrange

我想突出显示(将 css 应用到)某个文本范围,由其开始和结束位置表示。这比看起来更难,因为文本中可能还有其他需要忽略的标签。

例子:

<div>abcd<em>efg</em>hij</div>

highlight(2, 6) 需要在不移除标签的情况下突出显示 "cdef"。

我已经尝试过使用 TextRange 对象,但没有成功。

提前致谢!

最佳答案

下面是一个函数,用于将选择设置为特定元素内的一对字符偏移量。这是一个天真的实现:它没有考虑任何可能不可见的文本(例如,通过 CSS 或在 <script><style> 元素内)并且可能存在浏览器差异(IE 与其他所有内容)带有换行符,并且不考虑折叠的空白(例如 2 个或多个连续的空格字符折叠到页面上的一个可见空间)。但是,它确实适用于所有主要浏览器中的示例。

对于另一部分,突出显示,我建议使用 document.execCommand()为了那个原因。您可以使用我下面的功能来设置选择,然后调用 document.execCommand() .您需要使该文档在非 IE 浏览器中暂时可编辑,才能使命令生效。请在此处查看我的答案以获取代码:getSelection & surroundContents across multiple tags

这里有一个 jsFiddle 示例,展示了整个事情,适用于所有主要浏览器:http://jsfiddle.net/8mdX4/1211/

以及选择设置代码:

function getTextNodesIn(node) {
    var textNodes = [];
    if (node.nodeType == 3) {
        textNodes.push(node);
    } else {
        var children = node.childNodes;
        for (var i = 0, len = children.length; i < len; ++i) {
            textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
        }
    }
    return textNodes;
}

function setSelectionRange(el, start, end) {
    if (document.createRange && window.getSelection) {
        var range = document.createRange();
        range.selectNodeContents(el);
        var textNodes = getTextNodesIn(el);
        var foundStart = false;
        var charCount = 0, endCharCount;

        for (var i = 0, textNode; textNode = textNodes[i++]; ) {
            endCharCount = charCount + textNode.length;
            if (!foundStart && start >= charCount
                    && (start < endCharCount ||
                    (start == endCharCount && i <= textNodes.length))) {
                range.setStart(textNode, start - charCount);
                foundStart = true;
            }
            if (foundStart && end <= endCharCount) {
                range.setEnd(textNode, end - charCount);
                break;
            }
            charCount = endCharCount;
        }

        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (document.selection && document.body.createTextRange) {
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.collapse(true);
        textRange.moveEnd("character", end);
        textRange.moveStart("character", start);
        textRange.select();
    }
}

关于javascript - 使用 JavaScript 突出显示文本范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6240139/

相关文章:

javascript - 媒体上的导航无法获得 100% 的宽度

c# - 在具有扩展选择模式的列表框中单击取消选择

java - JList - 设置允许的选择组合

javascript - 在插入符位置 (IE) 将文本插入可编辑的 IFRAME

javascript - createTextRange - IE8 中的奇怪行为

Javascript 闭包和回调 - 变量值在回调后不会保留

javascript - 在 jQuery 中将多个事件附加到单个函数

JavaScript:Jasmine 错误:预期 { 0 : HTMLNode, length : 1 } 为 '#containers'

javascript - Highcharts 选择事件禁用突出显示效果

c# - 如何在 Silverlight 中使用 TextRange?