REGEX - 突出超过19个字符的部分

时间:2013-12-01 16:03:23

标签: javascript regex dom contenteditable

您好,

我在div[contenteditable="true"]中有一些文字,我应该突出显示(span.tooLong)部分超过19个字符的限制。 div中的内容可能包含HTML标记或实体,计算到19时应忽略这些内容。

Twitter有类似的方式来突出太长的推文:

Twitter's highlight

示例:

  • This is textThis is text
  • This is just too long textThis is just too lo<span class="tooLong">ng text</span>
  • This <b>text</b> has been <i>formatted</i> with HTMLThis <b>text</b> has been <span class="tooLong"><i>formatted</i> with HTML</span>

如何在JavaScript中实现此功能?

(我想尽可能多地使用正则表达式)

2 个答案:

答案 0 :(得分:5)

好的......这里有一些我觉得适合你的代码,或者至少可以开始使用。

基本上,你需要找到超过19个字符的正则表达式是这样的:

var extra = content.match(/.{19}(.*)/)[1];

所以,我整理了一份关于如何使用它的示例文档。

查看 DEMO

这是我正在使用的Javascript(我在这里使用jQuery作为定位器,但是这可以很容易地修改为使用直接Javascript ...我只是喜欢jQuery这样的东西)...

$(document).ready(function() {
  $('#myDiv').keyup(function() {
    var content = $('#myDiv').html();
    var extra = content.match(/.{19}(.*)/)[1];

    $('#extra').html(extra);

    var newContent = content.replace(extra, "<span class='highlight'>" + extra + "</span>");
    $('#sample').html(newContent);
  });
});

基本上,我有三个DIV设置。一个供您输入文字。一个显示超过19个字符限制的字符。还有一个可以展示你如何突出多余的角色。

我的代码示例没有检查html标记,因为有太多的东西无法尝试和处理......但是应该为您提供一个很好的起点,以确定它是如何工作的。

注意:您可以使用此链接查看我编写的完整代码:http://jsbin.com/OnAxULu/1/edit

答案 1 :(得分:4)

这是一个使用我的Rangy库的答案。它使用Class ApplierTextRange模块在​​可编辑内容中的字符范围上应用样式,同时保留选择。它还使用可配置的debounce间隔来防止编辑器性能的低迷。此外,它应该适用于旧的IE。

演示:http://jsfiddle.net/timdown/G4jn7/2/

示例代码:

var characterLimit = 40;
var debounceInterval = 200;

function highlightExcessCharacters() {
    // Bookmark selection so we can restore it later
    var sel = rangy.getSelection();
    var savedSel = sel.saveCharacterRanges(editor);

    // Remove previous highlight
    var range = rangy.createRange();
    range.selectNodeContents(editor);
    classApplier.undoToRange(range);

    // Store the total number of characters
    var editorCharCount = range.text().length;

    // Create a range selecting the excess characters
    range.selectCharacters(editor, characterLimit, editorCharCount);

    // Highlight the excess
    classApplier.applyToRange(range);

    // Restore the selection
    sel.restoreCharacterRanges(editor, savedSel);
}

var handleEditorChangeEvent = (function() {
    var timer;

    function debouncer() {
        if (timer) {
            timer = null;
        }
        highlightExcessCharacters();
    }

    return function() {
        if (timer) {
            window.clearTimeout(timer);
        }
        timer = window.setTimeout(debouncer, debounceInterval);
    };
})();

function listen(target, eventName, listener) {
    if (target.addEventListener) {
        target.addEventListener(eventName, listener, false);
    } else if (target.attachEvent) {
        target.attachEvent("on" + eventName, listener);
    }
}

rangy.init();
var editor = document.getElementById("editor");
var classApplier = rangy.createClassApplier("overrun");

// Set up debounced event handlers
var editEvents = ["input", "keydown", "keypress", "keyup",
                  "cut", "copy", "paste"];

for (var i = 0, eventName; eventName = editEvents[i++]; ) {
    listen(editor, eventName, handleEditorChangeEvent);
}