如何在动态生成的文本中突出显示可编辑的单词?

时间:2013-12-04 22:25:53

标签: javascript html css

简介

我正在创建一个内容编辑器,我想在其中添加选择要在输入内容时突出显示的单词的功能。

此时我实现搜索#dynamicWord中选择的任何单词,然后键入#contentAreaContainer并通过在关键字周围添加 em 并为 em <设置样式来为其指定红色边框/ em>通过CSS:

守则的一部分:

<div class="word">
      Dynamic word to highlight: <input name="dynamic_word" id="dynamicWord" value="Enter word..">
</div>

<div id="contentAreaContainer" oninput="highlighter()">
    <textarea id="contentArea"></textarea>
</div>

function highlighter()
{
var contentAreaContainer = document.getElementById('contentAreaContainer');
var dynamicWord = document.getElementById('dynamicWord').value;
wrapWord(contentAreaContainer, dynamicWord);
};

wrapWord()确实:

function wrapWord(el, word)
{
var expr = new RegExp(word, "i");
var nodes = [].slice.call(el.childNodes, 0);
for (var i = 0; i < nodes.length; i++)
{
    var node = nodes[i];
    if (node.nodeType == 3) // textNode
    {
        var matches = node.nodeValue.match(expr);
        if (matches)
        {
            var parts = node.nodeValue.split(expr);
            for (var n = 0; n < parts.length; n++)
            {
                if (n)
                {
                    var em = el.insertBefore(document.createElement("em"), node);
                    em.appendChild(document.createTextNode(matches[n - 1]));
                }
                if (parts[n])
                {
                    el.insertBefore(document.createTextNode(parts[n]), node);
                }
            }
            el.removeChild(node);
        }
    }
    else
    {
        wrapWord(node, word);
    }
  }
}

em{border: 1px solid red;}

问题:

现在,此时每次输入#contentAreaContainer时,所选关键字会在#contentAreaContainer中突出显示一小段时间,因为在输入时会触发highlighter()。但它应该在找到之后保持突出显示而不是仅仅是输入。

  1. 我需要oninput用wrapWord()搜索#dynamicWord值,而有些人正在输入;
  2. 每次找到#dynamicWord值时,都应永久获取 em
  3. 那么,在动态关键字被编辑之前,我怎样才能“保存”找到的关键字并永久地给它们元素?

    检查 DEMO version

    解决:

    使用setTimeout()而不是oninput我设法使高亮显示看起来不变。改变:

    function highlighter()
    {
    var contentAreaContainer = document.getElementById('contentAreaContainer');
    var mainKeyword = document.getElementById('main_keyword').value;
    wrapWord(contentAreaContainer, mainKeyword);
    repeater = setTimeout(highlighter, 0.1);
    }
    highlighter();
    

    我从#contentAreaContainer中删除了oninput =“highlighter()”。

1 个答案:

答案 0 :(得分:1)

您正在尝试突出显示textarea中的字词。据我所知,textarea不支持内部的html元素。如果你这样做,只需将它们显示为文本。

因此您需要使用可编辑的div。这是一个普通的div,但如果添加属性:

contentEditable="true"

div就像textarea一样,唯一不同的是它现在处理html元素。我还需要将onchange事件更改为onkeyup事件。可编辑的div不支持onchange事件,因此不会触发突出显示。这个div的HTML看起来像:

<div contentEditable="true" id="contentArea">Test text with a word in it</div>

以下是小提琴中的工作代码:http://jsfiddle.net/Q6bGJ/当您在textarea中输入新字符时,您的关键字会突出显示。

然而,仍然存在问题。您可以使用em元素包围关键字。这导致每次击键时都会围绕它。现在你最终围绕关键字宽度很多。如何解决这个问题,我接受你的挑战。