<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      vue實(shí)現(xiàn)聊天+圖片表情功能

      項(xiàng)目需求是這樣的:要求實(shí)現(xiàn)類似于微信聊天一樣,表情+文字效果 “文字效果??????”

      表情包三種方案

      表情包的實(shí)現(xiàn)其實(shí)可以分為以下三種情況:

      1. 表情包:點(diǎn)擊表情--直接發(fā)送大表情(這種方案其實(shí)就是發(fā)送了一張定義好的圖片而已)
      2. emoji圖標(biāo)表情:系統(tǒng)可識(shí)別的emoji圖標(biāo)表情,這種表情實(shí)現(xiàn)起來(lái)相對(duì)麻煩一些,其實(shí)這種方法emoji我們可以當(dāng)成一個(gè)2位字符的特殊文字去處理
        • 推薦emoji網(wǎng)址:emojis
          • 案例:禾蛙招聘網(wǎng)站
      3. 自定義表情:一版是設(shè)計(jì)畫好的,需要我們實(shí)現(xiàn)文字+表情進(jìn)行發(fā)送和回顯的
        • 思路1:我們?cè)邳c(diǎn)擊單個(gè)表情的時(shí)候輸入框內(nèi)需要添加表情,這是輸入框內(nèi)表情可以用‘[微笑]‘這種方式代替。只有在回顯的時(shí)候去識(shí)別特殊表示,再用表情去替換掉即可
          • 案例:BOSS直聘網(wǎng)站
        • 思路2:輸入框也需要是表情的回顯,這種方法就相對(duì)麻煩了一些
          • 案例:微信客戶端

      實(shí)現(xiàn)

      這里針對(duì)自定義表情包的思路2,進(jìn)行實(shí)現(xiàn),個(gè)人認(rèn)為也是最麻煩的實(shí)現(xiàn)
      實(shí)現(xiàn)效果
      這里只針對(duì)輸入框進(jìn)行實(shí)現(xiàn),對(duì)于數(shù)據(jù)傳遞給后端,消息的回顯這里就不進(jìn)行闡述了,想必大家也有自己更好的設(shè)計(jì)方法。

      1、布局

      大家可能會(huì)想到輸入?yún)^(qū)域可以用用input,或者是textarea標(biāo)簽,但針對(duì)‘文字+自定義圖片表情’是不太適用的,不過對(duì)于其他的實(shí)現(xiàn)方案還是可行的。
      實(shí)現(xiàn)思路

      • 采用div+ contenteditable="true"屬性
        • 舉例:'

          這是一個(gè)可編輯段落。

          '

      contenteditable屬性:

      • 屬性指定元素內(nèi)容是否可編輯。
      • 所有主流瀏覽器都支持 contenteditable 屬性
      • 設(shè)置了true:該標(biāo)簽?zāi)J(rèn)就存在了@fcous,@input等事件函數(shù)
      • 注意: 當(dāng)元素中沒有設(shè)置 contenteditable 屬性時(shí),元素將從父元素繼承。
      描述
      true 指定元素是可編輯的
      false 指定元素是不可編輯的
          <div
            id="emojiText"
            contenteditable="true"
            ref="edit"
            placeholder="請(qǐng)輸入內(nèi)容"
          ></div>
      

      2、實(shí)現(xiàn)

      這里實(shí)現(xiàn)思路包括三個(gè)方向:

      1. 添加表情,添加文字
      2. 獲取輸入的消息內(nèi)容,傳遞給后端
      3. 拿到特殊消息體'[微笑]',渲染對(duì)應(yīng)的表情

      添加表情,添加文字
      輸入文字:?jiǎn)渭兊妮斎胛淖制鋵?shí)很簡(jiǎn)單,思路就是可編輯區(qū)域可輸入對(duì)應(yīng)的文本內(nèi)容
      添加表情:實(shí)現(xiàn)思路是,再點(diǎn)擊添加表情時(shí)就是講表情地址生成<img>標(biāo)簽插入到可編輯區(qū)域內(nèi)
      添加表情存在的問題:
      問題1:添加表情時(shí)光標(biāo)不會(huì)聚焦到可編輯區(qū)域
      問題2:添加表情無(wú)法添加到光標(biāo)定位的位置上
      問題1解決方案
      添加表情時(shí)檢查是否聚焦,無(wú)聚焦執(zhí)行fcous強(qiáng)制聚焦

      let obj = this.$refs.edit; // obj 是可編輯的div
          let range, node;
          if (!obj.hasfocus) {
          obj.focus();
      }
      

      問題2解決方案
      window.getSelection:選擇的文本范圍或光標(biāo)的當(dāng)前位置。
      getRangeAt
      返回選區(qū)開始的節(jié)點(diǎn)(Node)。
      因?yàn)橥ǔG闆r下用戶只能選擇一個(gè)范圍,所以只有一個(gè)選區(qū)(range),此方法一般為getRangeAt(0)

      range = window.getSelection().getRangeAt(0);
      range.collapse(false); //光標(biāo)移至最后
      
      node = range.createContextualFragment(Img);
      let c = node.lastChild;
      range.insertNode(node);
      if (c) {
          range.setEndAfter(c);
          range.setStartAfter(c);
      }
      let j = window.getSelection();
      j.removeAllRanges();
      j.addRange(range);
      

      完整代碼

      <template>
        <div>
          <div
            id="emojiText"
            contenteditable="true"
            ref="edit"
            placeholder="請(qǐng)輸入內(nèi)容"
          ></div>
          <ul>
            <li v-for="item in emojis" :key="item.name">
              <img :src="item.path" alt="" @click="getEmojis" />
            </li>
          </ul>
          <button @click="senMsg">發(fā)送</button>
        </div>
      </template>
      
      <script>
      export default {
        components: {},
        data() {
          return {
            emojis: [
              {
                name: "[emoji-1]",
                path: require("./assets/emojis/m1.png"),
              },
              {
                name: "[微笑]",
                path: require("./assets/emojis/m2.png"),
              },
              {
                name: "[emoji-3]",
                path: require("./assets/emojis/m3.png"),
              },
            ],
          };
        },
        mounted() {},
        methods: {
          getEmojis(event) {
            let Img = `<img src="${event.target.src}" style='height:10px;'>`;
      
            let obj = this.$refs.edit; // obj 是可編輯的div
            let range, node;
            if (!obj.hasfocus) {
              obj.focus();
            }
            /* 
              window.getSelection:選擇的文本范圍或光標(biāo)的當(dāng)前位置。
              getRangeAt
                  返回選區(qū)開始的節(jié)點(diǎn)(Node)。
                  因?yàn)橥ǔG闆r下用戶只能選擇一個(gè)范圍,所以只有一個(gè)選區(qū)(range),此方法一般為getRangeAt(0)
            */
            if (window.getSelection && window.getSelection().getRangeAt) {
              range = window.getSelection().getRangeAt(0);
              range.collapse(false); //光標(biāo)移至最后
      
              node = range.createContextualFragment(Img);
              let c = node.lastChild;
              range.insertNode(node);
              if (c) {
                range.setEndAfter(c);
                range.setStartAfter(c);
              }
              let j = window.getSelection();
              j.removeAllRanges();
              j.addRange(range);
            } else if (document.selection && document.selection.createRange) {
              document.selection.createRange().pasteHTML(Img);
            }
          },
          senMsg() {
            console.log(this.$refs.edit.innerHTML);
          },
          natchMsg() {
            let str = "比如‘[微笑]’asdtgsaghd[微笑]ggg";
            let newStr = str;
            this.emojis.forEach((item) => {
              console.log(str.indexOf(item.name));
              if (str.indexOf(item.name) > -1) {
                let Img = `<img src="${item.path}" style='height:10px;'>`;
                newStr = str.replaceAll(item.name, Img);
              }
            });
            console.log(newStr);
          },
        },
      };
      </script>
      
      <style lang='scss' scoped>
      #emojiText {
        width: 600px;
        height: 300px;
        border: 1px solid #111;
      }
      ul {
        display: flex;
        list-style: none;
      }
      li img {
        width: 20px;
        height: 20px;
      }
      .msgicon {
        width: 10px;
        height: 10px;
      }
      </style>
      ``
      posted @ 2021-11-24 13:12  雅痞_yuppie  閱讀(3754)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 少妇人妻av毛片在线看| 午夜精品区| 买车| 日韩人妻久久精品一区二区| 欧洲精品色在线观看| 平果县| 国产婷婷精品av在线| 国产免费一区二区不卡| 欧美日韩精品一区二区三区在线 | 久久亚洲人成网站| 波多野结衣的av一区二区三区 | 国内精品久久久久影院日本| 国产亚洲婷婷香蕉久久精品| 一区二区三区四区黄色片| 被拉到野外强要好爽| 国产亚洲精品AA片在线播放天| 精品国产不卡在线观看免费| 久久精品一本到99热免费| av无码精品一区二区乱子| 日本不卡一区| 国产一区二区精品久久呦| 99久久婷婷国产综合精品青草漫画| 丰满大爆乳波霸奶| 中文字幕一区有码视三区| 国产亚洲一二三区精品| 极品人妻videosss人妻| 国产偷国产偷亚洲高清午夜| a级黑人大硬长爽猛出猛进| 国产午夜福利视频在线| 天堂网在线.www天堂在线资源| 无码成人午夜在线观看| 四虎精品永久在线视频| 丝袜人妻一区二区三区网站| 成人网站免费观看永久视频下载| 久久精品国产99久久6| 国产精品啪| 婷婷99视频精品全部在线观看 | 无人区码一码二码三码区| 四虎永久播放地址免费| 久久99精品久久久久久9| 久久这里都是精品二|