javascript - 动态突出显示文本区域

标签 javascript

我希望通过指定背景颜色和一系列索引来突出显示文本区域中的文本。然后,我将随着用户键入不断动态地更改和更新突出显示的文本。

jquery.highlightTextarea几乎是完美的。问题在于,它似乎并不是真正设计为像这样动态更新突出显示的文本。除此之外,作者现在已经停产,不会再更新了。

我什至查看了Ace Code Editor ,但是基于简单索引突出显示的能力实际上并不存在(您必须基于行/列突出显示)。另外,对于我正在做的事情来说,这似乎有些过分了。

所以我正在寻找替代方案。除了我提到的功能之外,性能也是我优先考虑的事项。我想编制一份要考虑的库列表。有什么建议吗?

最佳答案

我终于找到了一些对我来说很有效的东西。我正在使用Ace Editor 。我在 Ace 和 CodeMirror 之间来回犹豫,最后选择了 Ace,因为我觉得这个特定的任务更简单一些,而且文档也更好。我说的很简单,但复杂的是我必须将索引范围转换为列/行范围,因为这是 Ace 中 Range 对象所期望的格式。

但这就是我想到的:

function HighlightMatches(matches) {
    var matchClass = "myMarker";
    var oldMarkers = inputEditor.session.$backMarkers;

    // clear out old markers
    for (var prop in oldMarkers) {
        if (oldMarkers[prop].clazz == matchClass) {
            inputEditor.session.removeMarker(oldMarkers[prop].id);
        }
    }

    if (matches && matches.length > 0) {
        var ranges = NormalizedRanges(GetInput(), matches);

        // add new markers
        for (var i = 0; i < ranges.length; i++) {
            inputEditor.session.addMarker(new Range(ranges[i].startRow, ranges[i].startCol, ranges[i].endRow, ranges[i].endCol), matchClass);
        }
    }
}    

function NormalizedRanges(input, matches) {
    var ranges = [];

    var startCol = 0;
    var endCol = 0;
    var startRow = 0;
    var endRow = 0;
    var currentMatch = 0;

    var matchStart = 0;
    var matchLength = 0;
    var matchEnd = 0;

    for (var i = 0; i < input.length; i++) {
        matchStart = matches[currentMatch].index;
        matchLength = matches[currentMatch].length;
        matchEnd = matchStart + matchLength;            

        // process match
        if (i >= matchStart && i <= matchEnd) {
            endCol = startCol;
            endRow = startRow;

            for (var k = 0; k < matchLength; k++) {
                endCol++;
                var advanceNewLine = AdvanceNewLine(input.substr(i + k, 2))
                if (advanceNewLine > 0) {
                    endRow++;
                    endCol = 0;
                    if (advanceNewLine == 2)
                        k++;
                }
            }

            ranges.push(new IndexRange(startCol, endCol, startRow, endRow));

            startCol = endCol;
            startRow = endRow;

            // set index to end of match
            i = matchEnd - 1;

            // advance current match
            currentMatch++;
            if (currentMatch == matches.length)
                return ranges;
        }
        else {
            // advance range
            startCol++;
            var advanceNewLine = AdvanceNewLine(input.substr(i, 2));
            if (advanceNewLine > 0) {
                startRow++;
                startCol = 0;
                if (advanceNewLine == 2)
                    i++;
            }
        }
    }

    return ranges;
}

function AdvanceNewLine(text) {
    if (text == '\r\n')
        return 2;
    else {
        var char = text.charAt(0);
        if (char == '\n' || text == '\r')
            return 1;
        else
            return 0;
    }           
}

function IndexRange(startCol, endCol, startRow, endRow) {
    this.startCol = startCol;
    this.endCol = endCol;
    this.startRow = startRow;
    this.endRow = endRow;
}

您只需调用 HighlightMatches 并传入一个 matches JSON 对象,该对象可能如下所示:

{"matches":[{"index":0,"length":1},{"index":4,"length":1}]}

关于javascript - 动态突出显示文本区域,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33321514/

相关文章:

javascript - 允许在输入文本上使用 'onblur' 事件单击 div

javascript - 如何添加 UMD 以便我可以在浏览器中使用我的模块并将其用作 NPM 模块?

javascript - 无法设置文本区域和复选框以在 mvc5 中设置值

javascript - 在 PHP 的 while 循环中更新多个日期列

javascript - 使用 jQuery $().find 解析带有命名空间的 XML

javascript - 在javascript中使用DOM设置文本阴影属性的值

javascript - 模拟实际的右键单击,而不仅仅是 mousedown 或 mouseup

javascript - ionic 阵列过滤器不过滤

javascript - Nodejs express4 - 未定义的 session

javascript - Jest 中的模拟 shell 命令输出