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

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

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

      富文本實現@選擇人

       

       

      準備工作

      npm i wangeditor --save
      npm i caret-pos --save

      組件:

      
      
      <!--富文本-->
      <div
          :id="editorEleId"
          @keydown="onKeyDownInput($event)"
          @click="onClickEditor"
      ></div>
      <!--  成員選擇  -->
       <div class="userPopupList" :style="{left: left + 'px', top: top + 'px'}" v-show="show">
            <el-input v-model="userName" ref="input"></el-input>
                  <ul>
                      <li
                          v-for="user in protectPersons.filter((item) => item.workNick.includes(this.userName))"
                          :key="user.userId"
                          @click="createSelectElement(user.workNick,user.userId)"
                      >
                          <el-avatar
                              :size="22"
                              :src="user.icon"
                              class="m-r-10" style="vertical-align: middle"
                          >
                              <img src="../../assets/images/defaultIcon.gif"/>
                          </el-avatar>
                          <span>{{user.workNick}}</span>
                      </li>
                  </ul>
      </div>
      .userPopupList{
          position: fixed;
          z-index: 9999;
          /deep/input{
              border:none;
              background: transparent;
          }
          ul{
              max-height: 200px;
              overflow-y: auto;
              border: 1px solid #dbdada;
              background: #fff;
              padding: 10px 10px 0;
              border-radius: 3px;
              li{
                  margin-bottom: 5px;
                  padding: 5px 10px;
                  &:hover{
                      background: #f6f5f5;
                  }
              }
          }
      }
      position:any = {};
      left:number = 0;
      top:number = 0;
      show:boolean = false;
      isRendering: boolean = false;
      userName: string = '';
      users:any = [];
        
      ...富文本初始化
      this.editor.config.onchange = () => {
      // 生成@的標簽的時候會觸發渲染、此時不要記錄光標坐標
      if (this.isRendering === false) {
      this.setRecordCoordinates() // 記錄坐標
      }else {
      this.isRendering = false;
      }
      };
      // 每次點擊獲取更新坐標
      onClickEditor() {
      this.setRecordCoordinates()
      }
      // 獲取當前光標坐標
      setRecordCoordinates() {
      try {
      // getSelection() 返回一個 Selection 對象,表示用戶選擇的文本范圍或光標的當前位置。
            if(!this.show){
            const selection:any = window.getSelection();
            this.position = {
            range: selection.getRangeAt(0),
            selection: selection
            }
            }
          } catch (error) {
      console.log(error, '光標獲取失敗了~')
      }
      }
      // keydown觸發事件 記錄光標
      onKeyDownInput(e:any) {
      const isCode = ((e.keyCode === 229 && e.key === '@') || (e.keyCode === 229 && e.code === 'Digit2') || e.keyCode === 50) && e.shiftKey
      if (isCode) {
      this.setRecordCoordinates(); // 保存坐標
      this.getPosition();
      // 顯示選擇框,定時原因:1、@會插入到input中,2、光標位置也是input的,會導致插入位置錯誤
      setTimeout(()=>{
      this.show = true
      this.$nextTick(()=>{
      (this.$refs.input as any).focus();
      })
      },200)
      }
      }
      //彈窗列表 - 選人 - 生成@的內容
      createSelectElement(name:string, id:string, type = 'default') {
      // 獲取當前文本光標的位置。
      const { range } = this.position
      // 生成需要顯示的內容
      let spanNodeFirst:any = document.createElement('span')
      spanNodeFirst.className = 'user-node'
      spanNodeFirst.style.color = '#409EFF'
      spanNodeFirst.innerHTML = `@${name}&nbsp;` // @的文本信息
      spanNodeFirst.dataset.id = id // 用戶ID、為后續解析富文本提供
      spanNodeFirst.contentEditable = false // 當設置為false時,富文本會把成功文本視為一個節點。

      // 需要在字符前插入一個空格否則、在換行與兩個@標簽連續的時候導致無法刪除標簽
      let spanNode = document.createElement('span');
      spanNode.innerHTML = '&nbsp;';

      //創建一個新的空白的文檔片段,拆入對應文本內容
      let frag = document.createDocumentFragment()
      frag.appendChild(spanNode);
      frag.appendChild(spanNodeFirst);
      frag.appendChild(spanNode);

      // 如果是鍵盤觸發的默認刪除面前的@,前文中我們沒有阻止@的生成所以要刪除@的再插入ps:如果你是數組遍歷的請傳入type 不然會一直刪除你前面的字符。
      if (type === 'default') {
      const textNode = range.startContainer;
      range.setStart(textNode, range.endOffset - 1);
      range.setEnd(textNode, range.endOffset);
      range.deleteContents();
      }
      this.isRendering = true;
      // 判斷是否有文本、是否有坐標
      if ((this.editor.txt.text() || type === 'default')&& this.position && range) {
      range.insertNode(frag)
      } else {
      // 如果沒有內容一開始就插入數據特別處理
      this.editor.txt.append(`<span data-id="${id}" style="color: #409EFF" contentEditable="false">@${name}&nbsp;</span>`)
      }
      this.show = false;
      this.userName = '';
      }
      // 獲取當前光標位置
      getPosition () {
      const ele:any = this.editor.$textElem.elems[0];
      const pos = position(ele)
      const off = offset(ele)
      const parentW = ele.offsetWidth
      // 這個是彈窗列表
      const childEle:any = document.getElementsByClassName("userPopupList")
      const childW = childEle.offsetWidth
      // 彈框偏移超出父元素的寬高
      if (parentW - pos.left < childW) {
      this.left = off.left - childW
      } else {
      this.left = off.left
      }
      this.top = off.top - 4
      }

      //提交評論
      sure(ev: any) {
      ...
      const users = document.querySelectorAll('.user-node');
      let userIds:string[] = [];
      users.forEach((item:any) => {
      userIds.push(item.getAttribute('data-id'))
      })
      ...
      }
      
      

       

      posted @ 2022-04-11 16:40  Jade_g  閱讀(758)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 人妻中文字幕在线视频无码| 国产精品福利自产拍在线观看| 国产亚洲精品久久久久久久软件| 国产偷窥熟女高潮精品视频| 久久精品国产91精品亚洲| 日日碰狠狠添天天爽| 亚洲欧洲一区二区免费| 蜜桃一区二区三区免费看| 亚洲 校园 欧美 国产 另类 | 嘉荫县| 人妻精品久久无码专区涩涩| av日韩在线一区二区三区| 麻豆果冻国产剧情av在线播放| 永和县| 午夜一区欧美二区高清三区| 男人扒女人添高潮视频| 国产精品亚洲综合色区丝瓜 | AV最新高清无码专区| 国产精品综合一区二区三区| 亚洲成人精品在线伊人网| 毛片在线播放网址| 亚洲精品日韩精品久久| 人妻另类 专区 欧美 制服| 久久亚洲2019中文字幕| 特黄特色的大片观看免费视频 | jizz视频在线观看| 中文字幕亚洲综合久久| 欧洲亚洲国内老熟女超碰| 开心一区二区三区激情| 亚洲中文无码av在线| 亚洲一区在线观看青青蜜臀| 亚洲国产精品一区在线看| 国产仑乱无码内谢| 人妻av无码系列一区二区三区| 国内少妇偷人精品视频| 日日猛噜噜狠狠扒开双腿小说| 国产亚洲精品综合一区二区| 国产免费播放一区二区三区| 亚洲区精品区日韩区综合区| 一区二区三区国产亚洲自拍 | 久久精品国产中文字幕|