怎么给javascript + div编辑框光标位置插入表情文字等?

效果界面如下图 [图片] 在文字中间点击插入光标位,然后点击插入按钮展示表情弹层,点击表情后在光标位置插入对应表情。使用的js获取光标位置方法 sel…
关注者
19
被浏览
9,614

3 个回答

还是自己来吧,完美实现,楼主上代码

代码1:div 设置contenteditable等于true作为编辑框时的光标位置插入文本

/** 
 *光标位置插入
 * 参数1 string 要插入的内容
 * 参数2 bool true 插入后选中插入内容,false不选中
**/function pasteHtmlAtCaret(html, selectPastedContent) {
    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
            // only relatively recently standardized and is not supported in
            // some 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);
            var firstNode = frag.firstChild;
            range.insertNode(frag);
            // Preserve the selection
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                if (selectPastedContent) {
                    range.setStartBefore(firstNode);
                } else {
                    range.collapse(true);
                sel.removeAllRanges();
                sel.addRange(range);
    } else if ( (sel = document.selection) && sel.type != "Control") {
        // IE < 9
        var originalRange = sel.createRange();
        originalRange.collapse(true);
        sel.createRange().pasteHTML(html);
        if (selectPastedContent) {
            range = sel.createRange();
            range.setEndPoint("StartToStart", originalRange);
            range.select();
}

代码2:textarea 光标位置插入文本


//JQ 扩展
(function ($) {
    $.fn.extend({
        insertAtCaret: function (myValue) {
            var $t = $(this)[0];
            if (document.selection) {
                this.focus();
                sel = document.selection.createRange();
                sel.text = myValue;
                this.focus();
            } else{
                if ($t.selectionStart || $t.selectionStart == '0') {
                    var startPos = $t.selectionStart;
                    var endPos = $t.selectionEnd;
                    var scrollTop = $t.scrollTop;
                    $t.value = $t.value.substring(0, startPos) + myValue + $t.value.substring(endPos, $t.value.length);
                    this.focus();
                    $t.selectionStart = startPos + myValue.length;
                    $t.selectionEnd = startPos + myValue.length;
                    $t.scrollTop = scrollTop;
                } else {
                    this.value += myValue;
                    this.focus();
})(jQuery);

最近刚好碰到这个问题,虽然离提出问题已经过了半年了,本着前人栽树后人乘凉的精神,还是回答一下。

效果:


1.给用作富文本编辑的div添加contenteditable属性。

        <div id="editor" contenteditable="true"></div>

2.给表情图片添加click事件(我是把img表情放在li下的),div获取焦点,_insertimg()锁定编辑器中光标的位置,参数是img,也可以是文本。

	$("#Modal .emoji-list li").click(function(event) {
		var emoji = $(this).find("img").attr('src');
		$("#editor").focus();
		var source = '<img src="'+emoji+'">';
		_insertimg(source);
function _insertimg(str){
	var selection= window.getSelection ? window.getSelection() : document.selection;
	var range= selection.createRange ? selection.createRange() : selection.getRangeAt(0);
	if (!window.getSelection){
		document.getElementById('editor').focus();
		var selection= window.getSelection ? window.getSelection() : document.selection;
		var range= selection.createRange ? selection.createRange() : selection.getRangeAt(0);
		range.pasteHTML(str);
		range.collapse(false);
		range.select();
	else{
		document.getElementById('editor').focus();
		range.collapse(false);
		var hasR = range.createContextualFragment(str);
		var hasR_lastChild = hasR.lastChild;
		while (hasR_lastChild && hasR_lastChild.nodeName.toLowerCase() == "br" && hasR_lastChild.previousSibling && hasR_lastChild.previousSibling.nodeName.toLowerCase() == "br") {
			var e = hasR_lastChild;
			hasR_lastChild = hasR_lastChild.previousSibling;
			hasR.removeChild(e)
		range.insertNode(hasR);
		if (hasR_lastChild) {
			range.setEndAfter(hasR_lastChild);
			range.setStartAfter(hasR_lastChild)