1. 程式人生 > >可編輯的DIV(相容IE8)以及插入內容到游標位置

可編輯的DIV(相容IE8)以及插入內容到游標位置

在做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;
                }
            }
        });
    });
});