可编辑的DIV(兼容IE8)以及插入内容到光标位置

版权声明:本文博客都可以转载,我写博客只是为了整理自己的思路和回报天天在百度上搜索到的技术解决方案的人们 https://blog.csdn.net/canlynetsky/article/details/78844696

在做web版聊天程序时,往往需要将一个DIV设置为可编辑状态,并且可以插入表情。
插入表情时,不仅仅是在输入的文字最后追加表情,还可能在输入文本的中间,即光标位置插入表情(光标后还有文本)。
另外,还需要保证粘贴进来的文字必须是纯文本,不然百度搜索一篇文章粘贴进来,就太乱了。我们希望输入的文本都是纯文本,只有最基本的p标签或div标签。
通过各种百度搜索,我在项目中成功实施。
现将项目中的技术提取出来,形成一个小样例,大家可以参照使用。算是对网上提供这些素材的开发人员的回馈了。
html代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>可编辑的DIV(兼容IE8)</title>
    <style type="text/css">
    #content {
        width: 500px;
        height: 200px;
        border: 1px solid #CCC;
    }
    </style>
    <script src="../jquery.js"></script>
    <script src="./contenteditable.js"></script>
</head>

<body>
    <button id="insert" unselectable="on" onmousedown="return false">笑脸</button>
    <div id="content" contenteditable="true"></div>
    <script type="text/javascript">
    // 在光标位置插入html代码,如果dom没有获取到焦点则追加到最后
    function insertAtCursor(jsDom, html) {
        if (jsDom != document.activeElement) { // 如果dom没有获取到焦点,追加
            jsDom.innerHTML = jsDom.innerHTML + html;
            return;
        }
        var sel, range;
        if (window.getSelection) {
            // IE9 或 非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);
        }
    }

    $('#insert').click(function() {
        var html = ':)';
        insertAtCursor(document.getElementById('content'), html);
    });
    </script>
</body>

</html>

contenteditable.js代码:

/**
 * contenteditable="plaintext-only"在Firefox,ie浏览器中无效,这会导致DIV不可编辑。
 * 通过监听粘贴动作,过滤纯文本放入可编辑DIV的光标位置
 */
$(function() {
    $('[contenteditable]').each(function() {
        // 干掉IE http之类地址自动加链接
        try {
            document.execCommand("AutoUrlDetect", false, false);
        } catch (e) {}

        $(this).on('paste', function(e) {
            e.preventDefault();
            var text = null;

            if (window.clipboardData && clipboardData.setData) {
                // IE
                text = window.clipboardData.getData('text');
            } else {
                text = (e.originalEvent || e).clipboardData.getData('text/plain');
            }
            if (!text) {
                return false; // 粘贴图片时
            }
            if (document.body.createTextRange) {
                console.log('insert Text');
                if (document.selection) {
                    textRange = document.selection.createRange();
                } else if (window.getSelection) {
                    sel = window.getSelection();
                    var range = sel.getRangeAt(0);

                    // 创建临时元素,使得TextRange可以移动到正确的位置
                    var tempEl = document.createElement("span");
                    tempEl.innerHTML = "&#FEFF;";
                    range.deleteContents();
                    range.insertNode(tempEl);
                    textRange = document.body.createTextRange();
                    textRange.moveToElementText(tempEl);
                    tempEl.parentNode.removeChild(tempEl);
                }
                textRange.text = text;
                textRange.collapse(false);
                textRange.select();
            } else {
                // Chrome之类浏览器
                document.execCommand("insertText", false, text);
            }
        });
        // 去除Crtl+b/Ctrl+i/Ctrl+u等快捷键
        $(this).on('keydown', function(e) {
            // e.metaKey for mac
            if (e.ctrlKey || e.metaKey) {
                switch (e.keyCode) {
                    case 66: //ctrl+B or ctrl+b
                    case 98:
                    case 73: //ctrl+I or ctrl+i
                    case 105:
                    case 85: //ctrl+U or ctrl+u
                    case 117:
                        e.preventDefault();
                        break;
                }
            }
        });
    });
});

猜你喜欢

转载自blog.csdn.net/canlynetsky/article/details/78844696