如何给TextArea文本框中,点击按钮新增一个Tag标签

223 阅读1分钟

contenteditable

修改元素的可编辑性,使之可以编辑,html就给我们提供了这么个属性,要知道在一个普通元素内插入一个标签要比在textarea中要容易多了。

contenteditable 属性是 HTML5 中的新属性。规定是否可编辑元素的内容。比如将它设置在 div 上面将变为可以编辑的元素,类似文本输入框。

-webkit-user-modify

  • read-only: 默认值,元素只读,不可编辑;
  • read-write: 可以编辑,支持富文本;
  • read-write-plaintext-only: 可以编辑,不支持富文本;
  • write-only: 使元素仅用于编辑(几乎没有浏览器支持)

<template>
  <div class="tag-textarea">
    <div
      contenteditable="true"
      class="myTextArea"
      @input="handleInput"
      ref="inputTag"
      :id=contentId
      @focus="setDisabled(false)"
    ></div>
    <el-button size="small" :disabled="disabled" @click="addfactor">插入参数</el-button>
  </div>
</template>

<script>
export default {
  props: {
    paramsLength: {
      type: Number,
      default: 0
    }
  },
  name: "App",
  data() {
    return {
      Range: null,
      contentId: `content${this.getGuid()}`,
      disabled: true,
    };
  },
  mounted() {
    document.addEventListener("selectionchange", this.selecthandler);
  },
  beforeDestroy() {
    document.removeEventListener("selectionchange", this.selecthandler);
  },
  methods: {
    callBack(html) {
      // 执行回调函数
      this.$emit("callBack", html.replace(/<[^>]*>/g, ''));
      console.log(html.replace(/<[^>]*>/g, ''));
    },
    handleInput() {
      this.callBack(this.$refs.inputTag.innerHTML);
    },
    getGuid() {
      // 生成随机ID
      return `r${new Date().getTime()}d${Math.ceil(Math.random() * 1000)}`;
    },
    selecthandler() {
      const sel = window.getSelection();
      const range = sel ? (sel.rangeCount > 0 ? sel.getRangeAt(0) : null) : null;
      if (range && range.commonAncestorContainer.ownerDocument?.activeElement?.id === this.contentId) {
        this.saveRange(range);
      }
    },
    saveRange(range) {
      this.Range = range;
    },
    insertNode(node) {
      // 删掉选中的内容(如有)
      if (this.Range) {
        this.Range.deleteContents();
        this.Range.insertNode(node);
        this.callBack(this.$refs.inputTag.innerHTML);
      }
    },
    addTag(text) {
      const node = document.createElement("div");
      node.className = 'textarea-tag'
      node.innerText = text;
      // const cancelNode = document.createElement("span");
      // cancelNode.innerText = "✕";
      // cancelNode.style.color = "black";
      // cancelNode.onclick = (event) => {
      //   const parentElement = event.target.parentElement;
      //   if (parentElement && parentElement.parentNode) {
      //     parentElement.parentNode.removeChild(parentElement);
      //   }
      //   this.callBack(this.$refs.inputTag.innerHTML);
      // };
      // node.appendChild(cancelNode);
      this.insertNode(node);
      this.setDisabled(true);
    },
    addfactor() {
      this.addTag("${test}");
    },
    setDisabled(value) {
      this.disabled = value;
    },
  },
};
</script>

<style lang="scss">
.tag-textarea {
  .myTextArea {
    -webkit-user-modify: read-write-plaintext-only !important;
    border:1px solid #c0ccda;
    padding: 0px 15px;
    border-radius: 4px;
    overflow: hidden;
    box-sizing: border-box;
    word-break: break-word;
    height: 200px;
    width: 100%;
    transition: border-color 0.2s;
  }

  .myTextArea:focus {
    border-color: #409eff;
  }

  .myTextArea.is-disabled {
    background-color: #f5f7fa;
    cursor: not-allowed;
  }

  .textarea-tag {
    color: #c41d7f;
    background: #fff0f6;
    border-color: #ffadd2;
    -webkit-user-modify: read-only;
    display: inline;
    margin: 0 6px;
    font-size: 12px;
    padding-inline: 7px;
    border: 1px solid #d9d9d9;
    border-radius: 4px;
  }

  .el-button {
    margin-top: 10px;
  }
}


</style>