chatgpt的光标跟随字体显示

148 阅读1分钟

实现2个功能: 1.随着内容的变化,文本框的高度发生变化 2.光标跟随文字出现 知识:1.scrollHeight 滚动条的高度 2.字符位置的获取,通过createRange,框定区域,然后活动区域的位置getBoundingRect 代码可直接拷贝运行,只有一个文件。

  <div class="container">
    <div class="txt" ref="textBox"></div>
    <div class="cursor" v-if="isshow"></div>
  </div>
</template>
<script>
export default {
  data () {
    return {
      isshow: false,
      x: 10,
      y: 20,
      cont: '这段代码会输出转换后的HTML,你可以将它插入到你的网页中去。注意:marked库可以配置,以适应特定的HTML输出需求。上面的例子展示了默认的转换'
    }
  },
  mounted () {
    this.insertCont()
  },
  methods: {
    // 找到最后一个字符并插入一个字符
    lastStr(dom) {
      const addStr = document.createTextNode('梁')
      dom.appendChild(addStr)
      const range = document.createRange()
      range.setStart(addStr, 0)
      range.setEnd(addStr, 0)
      const rect = range.getBoundingClientRect()
      const domRect = dom.getBoundingClientRect()
      console.log(rect)
      this.x = rect.x - domRect.x
      this.y = rect.y - domRect.y
      dom.removeChild(addStr)
    },
    insertCont () {
      setInterval(() => {
        if (this.cont.length <= 0) {
          this.isshow = false
          return
        }
        this.isshow = true
        const cont = this.cont.substring(0,1)
        this.lastStr(this.$refs.textBox)
        this.$refs.textBox.innerHTML += cont
        this.putHander(this.$refs.textBox)
        this.cont = this.cont.substring(1)
      },100)
    },
    putHander(dom) {
      dom.style.height = 'auto'
      dom.style.height = dom.scrollHeight + 'px'
    }
  }
}
</script>
<style scoped>
.container{
  position: relative;
}
.txt {
  position: relative;
  left: 0;
  top: 0;
  width: 200px;
  resize: none;
  display: block;
  line-height: 2;
  overflow: auto;
  outline: none;
  background-color: black;
  color: white;
  
  text-align: left;
}
.cursor{
  content: '';
  width: 10px;
  height: 16px;
  background: red;
  animation: toggle 0.6s infinite;
  opacity: 0;
  transform: translateY(3px);
  position:absolute;
  left: calc(v-bind(x) * 1px);
  top: calc(v-bind(y) * 1px);
}
@keyframes toggle {
  30% {
    opacity: 1;
  }
}
</style>