0

我目前正在使用原生 JS,并且正在尝试在 contenteditable div 中构建突出显示文本功能。我已经成功构建了突出显示功能,但是当我想使用单个按钮在突出显示和取消突出显示文本之间切换时遇到了问题。所以我通过

var selectedText = window.getSelection();
var range = selectedText.getRangeAt(0);

我正在使用作为范围对象函数的环绕内容来包装选定的文本。

var wrapper = document.createElement("span");
wrapper.setAttribute("class","highlight");

但是现在当我试图取消突出显示突出显示的文本的某些部分和纯文本的某些部分时,自然行为应该取消突出显示突出显示的文本并突出显示纯文本。为了实现这一点,我通过克隆范围

var clone = range.cloneContents()
var nodeInBetween = clone.childNodes //array of nodes between the start and end nodes.

现在我面临两个问题。首先,我需要删除 span.highlight 节点并再次将其替换为 TextNode 以使其未突出显示,并且我需要一些方法来用 span 包装 textnode。不幸的是,没有办法将文本节点包装为范围变量。

4

1 回答 1

0

我在这个 jsFiddle中尝试了一个(递归)荧光笔方法。它可能对你有用。实际方法:

function highLight(term,root,forElements,styleclass){
    root = root || document.querySelector('body');
    term = term instanceof Array ? term.join('|') : term;

    if (!term) {throw TypeError('Highlighter needs a term to highlight anything');}

    forElements = forElements && forElements instanceof Array 
                    ? forElements.join(',') 
                    : /string/i.test(typeof forElements) ? forElements : '*';
    styleclass = styleclass || 'highlight';

    var allDiv = root.querySelectorAll(forElements),
        re = RegExp(term,'gi'),
        highlighter = function(a){return '<span class="'+styleclass+'">'+a+'</span>'};

    for (var i=0; i<allDiv.length; i+=1){
        // recurse children
        if (allDiv[i].querySelectorAll(forElements).length){
            highLight.call(null,term, allDiv[i],forElements,styleclass);
        }
        // replace term(s) in text nodes
        var node = allDiv[i];
        for (node=node.firstChild; node; node=node.nextSibling) {
            if (node.nodeType===3){
                var re = RegExp(term,'gi');
                node.data = node.data.replace(re,highlighter);
            }
        }

    }
    //finally, replace all text data html encoded brackets
    root.innerHTML = root.innerHTML
                      .replace(/&lt;/gi,'<')
                      .replace(/&gt;/gi,'>');
}
于 2013-08-19T10:34:21.730 回答