javascript - 在 contenteditable div 中突出显示的文本周围添加 html 标签

标签 javascript jquery selection contenteditable

我有一个 contenteditable div,我想在用户选择文本并单击按钮后在突出显示的文本周围添加一些 html 标签..

这是示例代码。它有一些 JavaScript 代码,但我无法让它按预期工作。实际上我玩了很多。

https://codepen.io/anon/pen/ybzzXZ

附注当我们解决如何在其周围添加 html 标签后,我将添加 , 或 like html 标签。

我在 stackoverflow 中找到了一些 js 代码。

function getSelectionText() {
    var text = "";
    if (window.getSelection) {
        text = window.getSelection().text;
    } else if (document.selection && document.selection.type != "Control") {
        text = document.selection.createRange().text;
    }
    return text;
}

另一个是

function replaceSelectionWithHtml(html) {
    var range;
    if (window.getSelection && window.getSelection().getRangeAt) {
        range = window.getSelection().getRangeAt(0);
        range.deleteContents();
        var div = document.createElement("div");
        div.innerHTML = html;
        var frag = document.createDocumentFragment(), child;
        while ( (child = div.firstChild) ) {
            frag.appendChild(child);
        }
        range.insertNode(frag);
    } else if (document.selection && document.selection.createRange) {
        range = document.selection.createRange();
        range.pasteHTML(html);
    }
}

最佳答案

您提出的问题存在几个挑战。

首先,您需要收集所选文本值。您已经发布了一些示例 - 在其他地方有相当详细的记录,因此我将由您来隔离该问题。

接下来您需要突出显示所选文本。通常,为了突出显示 HTML 中的某些内容,我们将希望突出显示的文本包装在一个简单的元素(例如 Span)中,然后为该 Span 提供一些类 - 例如,通常这用于为某些文本提供背景颜色。 <span style='background-color:yellow'>some text</span> - 理解那部分并不难。

接下来的挑战是将“发现的文本”与突出显示结合起来。很容易将文本换行,如 span 中所示。前面提供的示例。然而,一个问题是,如果该文本之前位于其他一些 HTML 元素中,我们需要确保发现中的文本选择不包含在另一个元素中,如果是,则处理该问题。让我们用这个跨度来说明这一点:Howdy <span style='background-color:yellow'>some text</span> Some more .

现在,对于这个示例,假设我们希望突出显示文本“Howdy some” - 该文本的一部分先前位于具有我们所需标记的范围内,因此我们必须首先提取该文本,删除该“突出显示”,然后突出显示“Howdy some”的新文本“选择”。

提供一个说明。在文本框中输入“This I Want”一词,看看它如何突出显示。

这不完全是您的问题,但它提供了“亮点”,您可以将其与选择器结合起来。我还没有完全审查这个错误,例如在“突出显示”中输入 HTML。

/* highlight words */
function findStringLimit(searchChar, searchCharIndex, searchedString) {
    return searchedString.substring(0, searchedString.lastIndexOf(searchChar, searchCharIndex));
};

function highlightWords(wordsy, text) { /* eliminate a bug with parenthesis */
    wordsy = wordsy.replace("(", "");
    wordsy = wordsy.replace(")", ""); /* escape other characters for bug */
    text = text.replace(";", "");
    text = text.replace("'", "&#39;");
    text = text.replace("<", "&lt;");
    text = text.replace(">", "&gt;");
    text = text.replace("&lt;span", "<span");
    text = text.replace('autoCompleteWord"&gt;', 'autoCompleteWord">');
    text = text.replace("&lt;/span", "</span");
    text = text.replace('span&gt;', 'span>');

    var re = '(' + wordsy + ')(?![^<]*(?:<\/span class=\"autoCompleteWord\"|>))';

    var regExp = new RegExp(re, 'ig');
    var sTag = '<span class="autoCompleteWord">';
    var eTag = "</span>";
    return text.replace(regExp, sTag + '$&' + eTag);
};

function parseAndHighlight(wordstring, htmlString) {
    var htmlStringUn = htmlString;

    var found = htmlStringUn.toLowerCase().indexOf(wordstring.toLowerCase(), 0);
    if (found >= 0) {
        htmlStringUn = highlightWords(wordstring, htmlStringUn);
    }
    else {
        //split and parse the beast
        var words = wordstring.split(/\W+/);

        var allPhrases = [];
        allPhrases.push(wordstring);
        var i = 0;
        i = words.length;
        while (i--) {
            allPhrases.push(findStringLimit(" ", allPhrases[(words.length - i) - 1].length, allPhrases[(words.length - i) - 1]));
        };

        i = allPhrases.length;
        while (i--) {
            if (allPhrases[i] != "") words = words.concat(allPhrases[i]);
        };
        i = words.length;
        while (i--) {
            htmlStringUn = highlightWords(words[i], htmlStringUn);
        };
    };
    return htmlStringUn;
}

$(document).on('change', '#myInput', function() {
    var myValue = $('#myInput').val(); //get what was typed
    $('#found').text(myValue);
    myValue = myValue.replace(/^\s+|\s+$/g, ""); //strip whitespace on ends
    $('#found').text(myValue + ':stripped:');
    var showText = $('#origshower').text();
    var newShowString = parseAndHighlight(myValue, showText); //my original highlighter
    $('#shower').html(newShowString);
});
#holder{border:red solid 2px; padding: 5px;}
#myInput{width:200px; background-color: aqua;}
span.autoCompleteWord /* this is the word(s) found */
{
    font-weight: bold;
    background-color: yellow;
    
}
#shower{border:lime 2px solid;}
<script
  src="https://code.jquery.com/jquery-1.12.4.min.js"
  integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
  crossorigin="anonymous"></script>

<div id='holder'>
    <input id='myInput' type='text' cols='60' rows='2' />Enter Text to match
</div>
<div id='origshower'>This is the span thistle with the whistle that I want matched is this neat</div>
<div id='shower'>none</div>
<div id='found'>enter</div>

关于javascript - 在 contenteditable div 中突出显示的文本周围添加 html 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44006680/

相关文章:

javascript - jQuery 日期和金额计算?

c# - 无法使用 jquery 访问 C# 方法

javascript - 单击索引中的链接后更改不同页面上的事件类 onClick?

WPF 数据网格选择问题

jquery - 使用 jQuery 文本字段选择全部/放置光标

javascript - 使用手动参数 FETCH 主干数据收集

javascript - fswrite 具有完整的 777 服务器协议(protocol)。安全的?

javascript - Ember.js 中带有普通 anchor 标记的动态 linkTo

javascript - 如何重写这段代码?

java - 用另一种颜色为 jtable 中的选定行着色