html 富文本編輯器相關--向編輯器內部插入文字圖片等各種dom元素 通用方法


 

有問題的插入方案

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <style>#edit{height:500px;width:500px;border:1px solid red;}</style>
</head>
<body>
<div id="edit" contenteditable></div>
<input type="text" id="emojiInput">
<button id="sendEmoji">發送表情</button>

<script>
    var sendEmoji = document.getElementById('sendEmoji')

    // 定義最后光標對象
    var lastEditRange;

    // 編輯框點擊事件
    document.getElementById('edit').onclick = function() {
        // 獲取選定對象
        var selection = getSelection()
        // 設置最后光標對象
        lastEditRange = selection.getRangeAt(0)
    }

    // 編輯框按鍵彈起事件
    document.getElementById('edit').onkeyup = function() {
        // 獲取選定對象
        var selection = getSelection()
        // 設置最后光標對象
        lastEditRange = selection.getRangeAt(0)
    }

    // 表情點擊事件
    document.getElementById('sendEmoji').onclick = function() {
        // 獲取編輯框對象
        var edit = document.getElementById('edit')
        // 獲取輸入框對象
        var emojiInput = document.getElementById('emojiInput')
        // 編輯框設置焦點
        edit.focus()
        // 獲取選定對象
        var selection = getSelection()
        // 判斷是否有最后光標對象存在
        if (lastEditRange) {
            // 存在最后光標對象,選定對象清除所有光標並添加最后光標還原之前的狀態
            selection.removeAllRanges()
            selection.addRange(lastEditRange)
        }
        // 判斷選定對象范圍是編輯框還是文本節點
        if (selection.anchorNode.nodeName != '#text') {
            // 如果是編輯框范圍。則創建表情文本節點進行插入
            var emojiText = document.createTextNode(emojiInput.value)

            if (edit.childNodes.length > 0) {
                // 如果文本框的子元素大於0,則表示有其他元素,則按照位置插入表情節點
                for (var i = 0; i < edit.childNodes.length; i++) {
                    if (i == selection.anchorOffset) {
                        edit.insertBefore(emojiText, edit.childNodes[i])
                    }
                }
            } else {
                // 否則直接插入一個表情元素
                edit.appendChild(emojiText)
            }
            // 創建新的光標對象
            var range = document.createRange()
            // 光標對象的范圍界定為新建的表情節點
            range.selectNodeContents(emojiText)
            // 光標位置定位在表情節點的最大長度
            range.setStart(emojiText, emojiText.length)
            // 使光標開始和光標結束重疊
            range.collapse(true)
            // 清除選定對象的所有光標對象
            selection.removeAllRanges()
            // 插入新的光標對象
            selection.addRange(range)
        } else {
            //debugger;
            // 如果是文本節點則先獲取光標對象
            var range = selection.getRangeAt(0)
            // 獲取光標對象的范圍界定對象,一般就是textNode對象
            var textNode = range.startContainer;
            // 獲取光標位置
            var rangeStartOffset = range.startOffset;
            // 文本節點在光標位置處插入新的表情內容
            textNode.insertData(rangeStartOffset, emojiInput.value)
            // 光標移動到到原來的位置加上新內容的長度
            range.setStart(textNode, rangeStartOffset + emojiInput.value.length)
            // 光標開始和光標結束重疊
            range.collapse(true)
            // 清除選定對象的所有光標對象
            selection.removeAllRanges()
            // 插入新的光標對象
            selection.addRange(range)
        }
        // 無論如何都要記錄最后光標對象
        lastEditRange = selection.getRangeAt(0)
    }
</script>
</body>
</html>
View Code

插入時 應該考慮的問題,

第一 原來容器內 有文本內容,現在在文本內容中間插入dom元素, 以上方法未解決,

第二 插入后定位到新插入的元素的位置

另附 :上面方法最有價值的地方在於 定義全局唯一range 和selection 對象,在每次變化時候記錄下最新的range和selection

      變化的時候包括

      1) blur 事件   2) onclick 事件  3) onkeyup  事件   --這些事件都有可能會改變光標位置

      4)代碼觸發時候 比如 用代碼向輸入框內插入一些節點時候 這時候應該也要記錄最新的selection 和range
 
        

ok的方案

/**
 * 在輸入區插入各種東東通用
 * @param html
 */
function insertImg(html) {
    var dthis = $("#input-content")[0];
    var sel = getSelection();
    if (window.getSelection) {
        // IE9 and non-IE
        sel = window.getSelection();
        if (sel.getRangeAt && sel.rangeCount) {
            range = sel.getRangeAt(0);
            range.deleteContents();
            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);
            if (lastNode) {
                range = range.cloneRange();
                range.setStartAfter(lastNode);
                range.collapse(true);
                sel.removeAllRanges();

                sel.addRange(range);
            }
        }
    } else if (document.selection && document.selection.type != 'Control') {
        $(dthis).focus(); // 在非標准瀏覽器中 要先讓你需要插入html的div 獲得焦點
        ierange = document.selection.createRange();// 獲取光標位置
        ierange.pasteHTML(html); // 在光標位置插入html 如果只是插入text 則就是fus.text="..."
        $(dthis).focus();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM