天天看點

添加emoji表情到編輯框,并且在任意光标後

依賴于emoji 庫,主要是雪碧圖實作表情的統一。

采用div标簽的contenteditable屬性實作編輯功能。 難點在于選擇表情時的光标位置儲存。實作任意光标位置插入表情。

實作一個小小的demo供大家參考, 共同學習!

添加emoji表情到編輯框,并且在任意光标後

部分代碼僅供參考,共同學習

難點部分;
1、選擇表情時的光标位置儲存
// 儲存上次光标位置資訊
var lastEditRange;
var editEle = document.getElementById('edit');
// 編輯框點選事件
editEle.onclick = function() {
    // 擷取標明對象
    var selection = getSelection();
    // 設定最後光标對象
    lastEditRange = selection.getRangeAt();
};

// 編輯框按鍵彈起事件
editEle.onkeyup = function() {
    // 擷取標明對象
    var selection = getSelection();
    // 設定最後光标對象
    lastEditRange = selection.getRangeAt();
};
           
2、在任意位置插入表情
function _insertimg(str) {
    var selection = window.getSelection
        ? window.getSelection()
        : document.selection;
    document.getElementById(elName).focus();
    if (lastEditRange) {
        // 存在最後光标對象,標明對象清除所有光标并添加最後光标還原之前的狀态
        selection.removeAllRanges();
        selection.addRange(lastEditRange);
    }
    var range = selection.createRange
        ? selection.createRange()
        : selection.getRangeAt);
    if (!window.getSelection) {
        var selection = window.getSelection
            ? window.getSelection()
            : document.selection;
        var range = selection.createRange
            ? selection.createRange()
            : selection.getRangeAt);
        range.pasteHTML(str);
        range.collapse(false);
        range.select();
    } else {
        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);
        }
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
    }
    // 無論如何都要記錄最後光标對象
    lastEditRange = selection.getRangeAt);
}
           
3、表情字元轉義
function emojiToUnicode(emoji) {
    var backStr = '';
    if (emoji && emoji.length > ) {
        for (var char of emoji) {
            var index = char.codePointAt();
            if (index > ) {
                var h =
                    '\\u' +
                    (Math.floor((index - ) / ) + ).toString(
                        
                    );
                var c =
                    '\\u' + ((index - ) %  + ).toString();
                backStr = backStr + h + c;
            } else {
                backStr = backStr + char;
            }
        }
        console.log(backStr);
    }
    return backStr;
}

function utf16toEntities(str) {
    //檢測utf16emoji表情 轉換為實體字元以供背景存儲
    var patt = /[\ud800-\udbff][\udc00-\udfff]/g;
    str = str.replace(patt, function(char) {
        var H, L, code;
        if (char.length === ) {
            //輔助平面字元(我們需要做處理的一類)
            H = char.charCodeAt(); // 取出高位
            L = char.charCodeAt(); // 取出低位
            code = (H - ) *  +  + L - ; // 轉換算法
            return '&#' + code + ';';
        } else {
            return char;
        }
    });
    return str;
}

console.log('ssss---->', emojiToUnicode('��adfa我們'));
// console.log('utf16toEntities222222--->', utf16toEntities('\ud83d\ude00adfa我們'))
$('.box').append(utf16toEntities('\ud83d\ude00adfa我們'));
           
emoji庫 GitHub位址 emoji庫位址

完整代碼位址 完整代碼下載下傳

繼續閱讀