PC端解析微信發送過來的emoji和在光標處插入emoji

最近公司的一個需求,需要在PC端接收並展示微信發送的消息,那麼如何解析微信發送過來的表情?如何在編輯框光標出插入表情?本文將會詳細的介紹如何解決這兩個問題。

一、PC端解析微信發送過來的emoji

首先,我們知道,emoji的展示實際是圖片的展示,input、textarea是沒法展示圖片的,所以我們用div裏contenteditable="true"屬性,即可編輯。其次我們要了解,微信發送一個表情過來,後臺數據庫接收到的是/::-O這種特殊字符串,當然,如果是[微笑]這種字符串處理方式也一樣,對照表可以參考微信默認表情代碼和圖片包,下載裏面的圖標到本地,並處理成如下格式

clipboard.png
頁面展示表情,只需要遍歷一下emoji數組,拼接一下圖片的url即可。

clipboard.png

當要處理某個字符串裏面的emoji時候,可遍歷emoji數組,將後臺接收的特殊字符串通過replace接口全局替換成對應的圖片,反之,同樣的方法將圖片轉化成微信可以解析成emoji的特殊字符,下面即是轉換的函數

   // 將特殊符號轉成對應表情 config.imgUrl圖片存放的url
      imgChangeEmoji(str) {
        emoji.forEach(element => {
          if (str && str.indexOf(element.code) > -1) {
            const effectCode = element.code.replace(/[.\\[\]{}()|^$?*+]/g, '\\$&'); // 轉義字符串中的元字符
            const pattern = new RegExp(effectCode, 'g');
            const imgUrl = `<img src='${config.imgUrl}/${element.img}'>`;
            str  =  str.replace(pattern, imgUrl);
          }
    
        });
        return str;
      }


       // 將對話中的表情圖片替換成特殊字符 config.imgUrl圖片存放的url
      emojiChangeImg(str) {
        emoji.map(element => {
          if (str && str.indexOf(element.img) > -1) {
            const imgUrl = `<img src="${config.imgUrl}/${element.img}">`;
            const pattern = new RegExp(imgUrl, 'g');
            str = str.replace(pattern, element.code);
          }
        });
        return str;
      }

需要特別注意的是,將特殊字符轉成RegExp的時候,必須先用replace進行轉義,即const effectCode = element.code.replace(/[.\[]{}()|^$?*+]/g, '\\$&'); 手寫轉義是無效的。有了上面的解析函數,你只需在發送消息前執行emojiChangeImg(str)函數即可,同樣的,如果想展示接收回來的消息,可以寫個指令運行imgChangeEmoji(str)函數。

二、光標處插入emoji

在div添加keyup和click事件,如下代碼(此處用的是angualr6)

 <div #editBox contenteditable="true"  (keyup)="handleInputChange()" (click)="handleClick()"></div>

在handleInputChange()和handleClick()和函數裏面設置最後光標對象

    // 獲取選定對象
  const selection = getSelection();
  // 設置最後光標對象
  this.lastEditRange = selection.getRangeAt(0);

選擇emoji圖片時創建一個img節點,並插入到最後光標位置,如下代碼

const img = new Image();
img.src = `${config.imgUrl}/${emoji.img}`;
const selection = getSelection();
if (this.lastEditRange) {
    // 存在最後光標對象,選定對象清除所有光標並添加最後光標還原之前的狀態
    selection.removeAllRanges();
    selection.addRange(this.lastEditRange);
}
// 選擇第一選區
const range = selection.getRangeAt(0);
range.insertNode(img);
range.collapse(false);

即可在光標處插入img。想了解更多光標對象可參考html元素contenteditable屬性如何定位光標和設置光標

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章