在contenteditable div

时间:2017-05-16 16:18:25

标签: javascript jquery selection contenteditable

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

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

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

P.S。在我们解决如何在其周围添加html标签之后,我会添加或者喜欢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);
    }
}

2 个答案:

答案 0 :(得分:1)

您遇到的问题存在一些挑战。

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

接下来,您需要突出显示所选文字。通常为了突出显示HTML中的内容,我们将我们希望在一个简单元素(如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”的新文本“选择”。

举例说明。在文本框中键入“我想要的”字样,看看它是如何突出显示的。

这不完全是您的问题,但它提供了可能与您的选择器结合的“突出显示”。我还没有完全审查过这个错误,例如输入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>

答案 1 :(得分:0)

您只需使用executeCommand致电formatBlock即可。您可以在这里找到更多信息: https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand