依賴于emoji 庫,主要是雪碧圖實作表情的統一。
采用div标簽的contenteditable屬性實作編輯功能。 難點在于選擇表情時的光标位置儲存。實作任意光标位置插入表情。
實作一個小小的demo供大家參考, 共同學習!
部分代碼僅供參考,共同學習
難點部分;
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庫位址
完整代碼位址 完整代碼下載下傳