美文网首页
聊天相关2>选中@用户整个交互

聊天相关2>选中@用户整个交互

作者: 衬fzy | 来源:发表于2023-02-20 16:53 被阅读0次
                      <!-- 输入框 -->
                     <div class="infoAdd2">
                        <el-input
                          id="keywordsText"
                          ref="keywordsText"
                          v-model="addOrderMsgForm.content"
                          maxlength="500"
                          class="keywordsText"
                          resize="none"
                          type="textarea"
                          :rows="2"
                          placeholder="请输入内容,点击回车发送。"
                          :disabled="form.status !== 1"
                          @keyup.enter.native="addOrderMsgFun($event)"
                          @input="contentFun()"
                          @keydown.up.native="onkeydownFun"
                          @keydown.down.native="onkeydownFun"
                          @focus="foucsFun()"
                        >
                        </el-input>
                      </div>
                      <!-- @选择框 -->
                   <div v-if="urlListShow" class="urlList scroll">
                      <div class="ul">
                        <div
                          v-for="(item, k) in orderMsgMemberArrList"
                          :key="k"
                          :class="itemK == k ? 'li li0' : 'li'"
                          @mouseenter="mouseenterItemKFun(k)"
                          @click="setAtFun(1)"
                        >
                          {{ item.truename + ':' + item.username }}
                        </div>
                      </div>
                    </div>
    

    js

      mounted() {
        document.onkeydown = this.showkey;// 监听按键
      },
      methods: {
        showkey(event) {
          let key = event.keyCode;
          this.keyCode = key
          let i = null
          switch (key) {
            case 37:// "按了←键!"
              this.urlListShowFun('-')
              break;
            case 38:// "按了↑键!"
              i = this.itemK - 1
              this.itemK = i < 0 ? 0 : i
              // this.itemK最小值只能0
              break;
            case 39:// "按了→键!"
              this.urlListShowFun('+')
              break;
            case 40:// "按了↓键!"
              i = this.itemK + 1
              this.itemK = i == this.orderMsgMemberArrList.length ? this.orderMsgMemberArrList.length - 1 : i
              // this.itemK最大值只能是卡选项的长度
              break;
            case 13:// "按了回车键!"
              if (this.urlListShow == true) { // 可选项dom框打开时
                this.setAtFun(0)
              }
              break;
          }
        },
        /** 输入框内容变化 */
        contentFun() {
          if (this.urlListShow == true && this.keyCode == 13) {
            // 按回车就不允许下一步判断,否弹出@选项框
            return
          }
          this.urlListShowFun()
        },
        /** 移到可选人员上,修改选中项 */
        mouseenterItemKFun(k) {
          this.itemK = k
        },
        /** 写入选中@人信息 ,number==1是点击选中的*/
        setAtFun(number) {
          const index0 = this.$refs.keywordsText.$refs.textarea.selectionStart // 写入前的光标位置
          setTimeout(() => {
            if (this.checkarr.length > 0) { // 是模糊搜索打开的
              let lastIndex = this.addOrderMsgForm.content.lastIndexOf('@', this.num)// 光标前的@位置
              let txt = this.addOrderMsgForm.content.substring(0, lastIndex)
              let index = this.$refs.keywordsText.$refs.textarea.selectionStart// 光标位置
              let txt2 = this.addOrderMsgForm.content.substring(index)
              // console.log(txt, JSON.stringify(txt2))
              let item = this.orderMsgMemberArrList[this.itemK]
              let atTxt = ` @${item.username} (${item.truename}) `
              if (txt2.length == 0 || JSON.stringify(txt2) == JSON.stringify('\n')) {
                this.addOrderMsgForm.content = txt + atTxt
              } else {
                console.log(JSON.stringify(txt2))
                this.addOrderMsgForm.content = txt + atTxt + txt2
              }
              this.$nextTick(() => {
                // 光标复位
                let ctrl = this.$refs.keywordsText.$refs.textarea
                console.log(ctrl.setSelectionRange)
                // if (ctrl.setSelectionRange) {
                ctrl.focus()
                ctrl.setSelectionRange(index0 - 1 + atTxt.length, index0 - 1 + atTxt.length)
                // } else if (ctrl.createTextRange) {
                //   console.log(2)
                //   var range = ctrl.createTextRange()
                //   range.collapse(true)
                //   range.moveEnd('character', index0)
                //   range.moveStart('character', index0)
                //   range.select()
                // }
              })
            } else { // 非模糊搜索打开的
              let index = this.$refs.keywordsText.$refs.textarea.selectionStart
              let txt = this.addOrderMsgForm.content.substring(0, index - 2 + number)// 回车会多一个空格所以减去2,鼠标点击就是正常的所以+number,number就是1
              let txt2 = this.addOrderMsgForm.content.substring(index)
              console.log(txt, JSON.stringify(txt2))
              let item = this.orderMsgMemberArrList[this.itemK]
              let atTxt = ` @${item.username} (${item.truename}) `
              if (txt2.length == 0) {
                this.addOrderMsgForm.content = txt + atTxt
              } else {
                this.addOrderMsgForm.content = txt + atTxt + txt2
              }
              this.$nextTick(() => {
                // 光标复位
                let ctrl = this.$refs.keywordsText.$refs.textarea
                console.log(ctrl.setSelectionRange)
                // if (ctrl.setSelectionRange) {
                ctrl.focus()
                ctrl.setSelectionRange(index0 + atTxt.length, index0 + atTxt.length)
                // } else if (ctrl.createTextRange) {
                //   console.log(2)
                //   var range = ctrl.createTextRange()
                //   range.collapse(true)
                //   range.moveEnd('character', index0)
                //   range.moveStart('character', index0)
                //   range.select()
                // }
              })
            }
            setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
              this.urlListShow = false
              this.checkarr = []
            }, 200)
          }, 0)
        },
        /** 是否弹出@候选列表框 */
        urlListShowFun(val) {
          let index = this.$refs.keywordsText.$refs.textarea.selectionStart// 光标所在位置
          this.num = index
          if (val == '-') { // 按了←键
            this.num = this.num - 1 < 0 ? 0 : this.num - 1
          } else if (val == '+') { // 按了→键
            this.num = this.num + 1 > this.addOrderMsgForm.content.length ? this.addOrderMsgForm.content.length : this.num + 1
          }
          let typeTxt = this.addOrderMsgForm.content.substring(this.num - 1, this.num)// 拿光标前面两个字符
          let lastIndex = this.addOrderMsgForm.content.lastIndexOf('@', this.num)
          console.log(this.num, typeTxt, lastIndex)
          if (typeTxt == '@' || JSON.stringify(typeTxt) == JSON.stringify('\n@')) {
            // 光标在@和换行的@位置后面
            this.itemK = 0// @选中位置
            this.urlListShow = true
            console.log('this.urlListShow1')
            this.orderMsgMemberArrList = this.orderMsgMemberArr
          } else if (lastIndex != -1) {
            // 光标在非@后面时的前面发现@
            let lastATtxt = this.addOrderMsgForm.content.substring(lastIndex + 1, this.num)// @符号后面:模糊搜索内容
            this.checkarr = this.orderMsgMemberArr.filter((v) => (v.truename.includes(lastATtxt)))
            // console.log(this.checkarr)
            if (this.checkarr.length > 0) {
              // 发现@后面内容跟聊天任意名字有模糊搜索相符的
              this.orderMsgMemberArrList = this.checkarr// checkarr 模糊筛选的可选项, orderMsgMemberArrList 渲染的选项
              this.itemK = 0// 当前@选中项
              this.urlListShow = true
            } else {
              setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
                this.urlListShow = false
                this.checkarr = []
              }, 200)
            }
          } else {
            setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
              this.urlListShow = false
              this.checkarr = []
            }, 200)
          }
        },
        onkeydownFun(event) {
          event.preventDefault(); // 禁止键盘上下按键时光标移动
        },
      }
    
    
    

    css

                  .infoAdd2 {
                    padding-top: 8px;
                    flex: 1;
    
                    ::v-deep {
                      .keywordsText {
                        overflow-y: hidden !important;
                        border: 1px solid #eee;
                      }
    
                      .el-textarea__inner {
                        border: 0;
                      }
                    }
                  }
    
                .urlList {
                  position: absolute;
                  left: 0;
                  bottom: 61px;
                  background: #fff;
                  width: 100%;
                  padding-top: 5px;
                  max-height: 230px;
                  overflow-y: auto;
    
                  .ul {
                    .li {
                      padding: 3px 46px;
                      cursor: pointer;
                    }
    
                    .li0 {
                      background: #1026F1;
                      color: #fff;
                    }
                  }
                }
    

    相关文章

      网友评论

          本文标题:聊天相关2>选中@用户整个交互

          本文链接:https://www.haomeiwen.com/subject/bddgkdtx.html