类@功能如何实现?

需求:实现一个功能,有多个span标签,内容为用户名,点击span标签,使其以tag的形式出现在一个contentEditable为true的div中,并且tag有背景色和4px的padding,tag不可编辑,当鼠标在div有焦点,则在当前焦点处插入tag,否则将tag加在最后面。

各位有什么实现方案吗

技术:在vue项目中。不要库。原生js实现

阅读 1.5k
3 个回答

光标后插入没有实现

<template>
  <div>
    <div class="user-list">
      <span
        v-for="user in userList"
        :data-username="user"
        @click="addTag"
        :key="user"
      >{{ user }}</span>
    </div>
    <div
      id="editor"
      contenteditable="true"
      fouce
    ></div>
  </div>

</template>

<script>
export default {
  data () {
    return {
      userList: ['1', '2', '3', '4']
    }
  },
  methods: {
    addTag (e) {
      const username = e.target.dataset.username;
      const tagElement = document.createElement('tag');
      tagElement.classList.add('tag');
      tagElement.textContent = username;
      tagElement.setAttribute('contenteditable', 'false');
      tagElement.style.backgroundColor = '#eee';
      tagElement.style.padding = '4px';

      const editor = document.getElementById('editor');
      console.log(document.activeElement, editor);
      if (document.activeElement === editor) { // 光标在编辑器内部
        const selection = window.getSelection();
        const range = selection.getRangeAt(0);
        range.deleteContents();
        range.insertNode(tagElement);
        range.collapse(false);
        selection.removeAllRanges();
        selection.addRange(range);
      } else { // 光标不在编辑器内部
        editor.appendChild(tagElement);
      }
    }
  }
}
</script>
<style lang="less" scoped>
.tag {
  display: inline-block;
  margin-right: 4px;
  margin-bottom: 4px;
}
span {
  display: inline-block;
  width: 50px;
  height: 50px;
  background: red;
  margin: 10px;
}
#editor {
  width: 500px;
  height: 500px;
  background-color: aqua;
}
</style>
推荐问题
宣传栏