键入contenteditable div时格式化标记系统

时间:2015-10-05 10:13:52

标签: javascript jquery html

我试图建立一个标记系统,比如一个twitter和facebook使用的地方你可以输入@并自动弹出你能够在帖子中标记的人(比如一个普通的社交网络)我花了几天时间试图找到一个解决方案因为我搜索过的所有答案都没有为我做好准备,但它并不起作用尽可能整洁。

示例(我可以输入我的帖子正文):

你好 @ andy22 你过得怎么样?

在您输入时,我需要将文本部分 @ andy22 格式化为另一种字体颜色。

这是我提出的解决方案,它几乎完美,因为粘贴文本时它也有效。但真正的问题是,当您将插入符号或光标放在该文本中的其他位置并且您在那里开始键入时,它始终会返回到文本的末尾。我想如果我想改变它,我实际上需要改变整个代码,那么我该怎么办?

HTML

<div class="editable" id="ee1" contenteditable="true"></div>

JS / JQuery

关于div的类型事件。

function tagType() {
var typing;
var format;
$('.editable').on('input', function(e) {
    typing = $(this);
    format = checkFormat(typing.getPreText());
    addFormat(format);
});
}

使用html函数获取文本

$.fn.getPreText = function () {
    var ce = $("<pre />").html(this.html());
    if ($.browser.webkit)
      ce.find("div").replaceWith(function() { return "\n" + this.innerHTML; });
    if ($.browser.msie)
      ce.find("p").replaceWith(function() { return this.innerHTML + "<br>"; });
    if ($.browser.mozilla || $.browser.opera || $.browser.msie)
      ce.find("br").replaceWith("\n");

    return ce.text();
};

在键入函数时更改文本的格式

function checkFormat(postbody) {
var body = postbody;
var format = '';
var flag_tagformat = 0;
var start_tagformat = '<span style="color:#0284fe">';
var end_tagformat = '</span>';

for(var i = 0; i < htmlCount(postbody); i++) {
    if(postbody[i] == ' ') {
        flag_tagformat = 0;
    }
    if(postbody[i] == '@' || flag_tagformat == 1) {
        format = format + start_tagformat + postbody[i] + end_tagformat;
        flag_tagformat = 1;
    } else {
        format = format + postbody[i];
    }
}

return format;
}

function htmlCount(thehtml) {
    thehtml = thehtml+'';
    return thehtml.length;
}

function addFormat(format) {
    $('.editable').empty();
    pasteHtmlAtCaret(format);
}

和最后一个,是将html粘贴到div中的函数,但是这也将插入符号/光标设置为最后一个字符,因为它粘贴了整个字符,所以它总是将它设置为最后一个字符,甚至如果你将插入符号/光标移动到文本的其他地方,它将键入第一个字符然后如果你继续键入它将继续键入但是在div本身的最后一个字符中。

function pasteHtmlAtCaret(html) {
var sel, range;
if (window.getSelection) {
    // IE9 and non-IE
    sel = window.getSelection();
    if (sel.getRangeAt && sel.rangeCount) {
        range = sel.getRangeAt(0);
        range.deleteContents();

        // Range.createContextualFragment() would be useful here but is
        // non-standard and not supported in all browsers (IE9, for one)
        var el = document.createElement("div");
        el.innerHTML = html;
        var frag = document.createDocumentFragment(), node, lastNode;
        while ( (node = el.firstChild) ) {
            lastNode = frag.appendChild(node);
        }
        range.insertNode(frag);

        // Preserve the selection
        if (lastNode) {
            range = range.cloneRange();
            range.setStartAfter(lastNode);
            range.collapse(true);
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
} else if (document.selection && document.selection.type != "Control") {
    // IE < 9
    document.selection.createRange().pasteHTML(html);
}
}

如果我需要提供更多信息,请告诉我,如果还有其他更好的方法,我也想知道。

我确实做了一些这些代码,但我也从这里拿了2个代码,我将给予赞誉。

Tim Down回答:Insert html at caret in a contenteditable div

Nick Craver回答:Extracting text from a contentEditable div

谢谢。

0 个答案:

没有答案