"VUE" editable div limits the number of characters

<template>
  <div class="home">
    <div
      id="sendMsg"
      contenteditable="true"
      class="textarea"
      @input="input"
      @compositionstart="compositStart"
      @compositionend="compositEnd"
      @paste="copyText"
      v-html="content"
    ></div>
    <div class="limit">{
    
    { textSize }}/100</div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        textSize: 0,
        lock: true,
        fullContent: '',
        content: '',   // 文本数据
      }
    },
    methods: {
      // 输入中文开始时
      compositStart(e) {
        this.lock = false;
        document.querySelector("#sendMsg").focus();
        document.execCommand("selectAll", false, null);
        document.getSelection().collapseToEnd();
      },
      // 输入中文结束时
      compositEnd(e) {
        this.lock = true;
        this.input(e);
      },
      input(e) {
        if(this.lock) {
          this.textSize = e.target.innerHTML.length
          if(this.textSize >= 100) {
            this.textSize = 100;
            this.fullContent = e.target.innerHTML.substring(0, 100);
            e.target.innerHTML = e.target.innerHTML.substring(0, 100);
          } else {
            this.fullContent = ''
          }
          this.content = e.target.innerHTML;
          this.textFocus();
        } else if (this.fullContent) {
          // 目标对象:超过100字时候的中文输入法
          // 原由:虽然不会输入成功,但是输入过程中字母依然会显现在输入框内
          // 弊端:谷歌浏览器输入法的界面偶尔会闪现
          e.target.innerHTML = this.fullContent;
          this.lock = true;
          this.textFocus();
        }
      },
      // 粘贴富文本转为纯文本
      copyText(e) {
        e.stopPropagation();
        e.preventDefault();
        let text = '', event = (e.originalEvent || e);
        if (event.clipboardData && event.clipboardData.getData) {
          text = event.clipboardData.getData('text/plain');
        } else if (window.clipboardData && window.clipboardData.getData) {
          text = window.clipboardData.getData('Text');
        }
        if (document.queryCommandSupported('insertText')) {
          document.execCommand('insertText', false, text);
        } else {
          document.execCommand('paste', false, text);
        }
      },
      // 文本输入框聚焦,焦点在最后位置
      textFocus() {
        setTimeout(() => {
          document.querySelector("#sendMsg").focus();
          document.execCommand("selectAll", false, null);
          document.getSelection().collapseToEnd();
        }, 0);
      },
    }
  }
</script>

<style scoped>
  .home{
    width: fit-content;
    position: relative;
  }
  .textarea{
    width: 600px;
    height: 300px;
    caret-color: auto;
    outline-style: none;
    border: 1px solid #D9D9D9;
    background-color: #F6F8FA;
    padding: 0 10px 20px;
    line-height: 26px;
    box-sizing: border-box;
    overflow-y: auto;
  }
  .limit{
    position: absolute;
    bottom: 1px;
    right: 1px;
    background-color: #fff;
    padding: 0 8px;
    line-height: 20px;
  }
</style>

tips:

Open source project address: https://gitee.com/chenswei/editable-div

Technical reference: https://blog.csdn.net/melodystars/article/details/103960259

Guess you like

Origin blog.csdn.net/qq_42660374/article/details/129625953
Recommended