文本域输入提示,自动补全功能

这篇具有很好参考价值的文章主要介绍了文本域输入提示,自动补全功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


<template>
  <div class="auto-container" :id="id">
    <el-input type="textarea" v-model="text" @input="handleChange" @change="changeVal" class="autoInput"></el-input>
    <div class="fix-el" ref="fixEl" :style="styleObj" v-show="show">
      <div class="auto-item" :class="{check:item.check}"  v-for="item in showOptions" 
      :key="item.variableCode" @click="itemClick(item)">{{ item.variableCode }}<span>{{item.variableName }}</span></div>
    </div>

  </div>
</template>
<script>


export default {
  props: {
    value: {
        type:String,
        default:''
      }
  },
  model: {
    prop: 'value',
    event:'change'
  },
  data() {
    return {
      text: '',
      saveText: '',
      lastText: '',
      styleObj: {
        top: '',
        left:''
      },
      str: '',
      options: [],
      show: false,
      showOptions: [],
      isEnd: true,
      cursorPos: 0,
      id:'auto-'+Date.now()
    }
  },
  watch: {
    value(nl, ol) {
      this.text = nl
    }
  },
  created() {
    this.text = this.value
    this.getVariable()
    document.addEventListener('keydown',this.handleKeybord)
  },
  methods: {
    changeVal(data) {
      this.$emit('change', data)
    },
    handleChange(data) {
      let pos = this.getCursorPos(data)
      this.styleObj.left = pos.x +'px'
      this.styleObj.top = pos.y + 'px'
      let str = data
      if (!this.isEnd) {
        str = data.slice(0,this.cursorPos)
      }
      this.getLastStr(str)
    },
    getCursorPos(text) {
      let textarea = document.querySelector(`#${this.id} textarea`)

      // 1. 光标在末尾
      // 2. 光标在中间
      this.cursorPos = textarea.selectionStart
      this.isEnd = this.cursorPos  == this.text.length
      if (!this.isEnd) {
        text = text.slice(0, this.cursorPos)
      }
      // 获取textarea内容宽度
      let contentHeight = textarea.offsetHeight
      let paddingLeft = getComputedStyle(textarea)['paddingLeft'].replace('px', '') / 1
      let paddingRight = getComputedStyle(textarea)['paddingRight'].replace('px', '') / 1
      let paddingTop = getComputedStyle(textarea)['paddingTop'].replace('px', '') / 1
      let lineHeight = getComputedStyle(textarea)['lineHeight'].replace('px', '') / 1
      let font = getComputedStyle(textarea)['font']

      // 下拉框距离文字间距
      let offset = 5

      let contentWidth = textarea.offsetWidth - paddingLeft - paddingRight

      
      var canvas =  document.createElement('canvas')
      var context = canvas.getContext('2d');
      context.font = font;
      let x = paddingLeft, y = lineHeight+paddingTop;
      let total = context.measureText(text).width;
      // 文本不超过一行
      if (total < contentWidth) {
        return {y:lineHeight+offset + paddingTop,x:total+ paddingLeft }
      } else {
       // 多行文本
        var arrText = text.split('');
        // 最后一行文本
        var line = '';
        for (var n = 0; n < arrText.length; n++) {
          var testLine = line + arrText[n];
          var metrics = context.measureText(testLine);
          var testWidth = metrics.width;
          if (testWidth > contentWidth && n > 0) {
            line = arrText[n];
            y += lineHeight;
          } else {
            line = testLine;
          }
        }
        x = context.measureText(line).width
        y = y> contentHeight? contentHeight+ offset :y
        return {x,y}
      }
      
    },
    getLastStr(data) {
      // 获取最后输入的英文单词
      let match = data.match(/[a-zA-Z]+$/)
      if (match) {
        this.str = match[0]
      }
      if (!data || !match) {
        this.showOptions = []
      } else {
        this.showOptions = this.options.filter(item => this.str && item.variableCode&&item.variableCode.includes(this.str))
      }
      this.showOptions.forEach((item,index) => item.check=index==0)
      this.show = this.showOptions.length > 0
      setTimeout(() => {
        let fixEl = document.querySelector(`#${this.id} .fix-el`)
        fixEl.scrollTop = 0
      })
    },
    handleKeybord(e) {
      let arrowMap = ['ArrowDown','ArrowLeft','ArrowUp','ArrowRight']
      // 有下拉框时禁用方向键
      if (arrowMap.includes(e.code) && this.show) {
        let i = this.showOptions.findIndex(item=>item.check)
        if (e.code == 'ArrowDown') {
          this.showOptions.map((item, index) => {
            if (i == this.showOptions.length - 1) {
              item.check = index==i
            } else {
              item.check = index == i+1
            }
          }) 
          this.scroll(true)         
        }
        if (e.code == 'ArrowUp') {
          this.showOptions.map((item, index) => {
            if (i == 0) {
              item.check = index == i
            } else {
              item.check = index == i - 1
            }
          })
          this.scroll(false)
        }
        e.preventDefault()
      }
      // 按下tab 或者回车
      if ((e.code == 'Tab' || e.code=='Enter')&&this.show) {
        this.joinText()
        e.preventDefault()
      }
    },
    scroll(type) {
      let fixEl = document.querySelector(`#${this.id} .fix-el`)
      let checkItem = document.querySelector(`#${this.id} .auto-item.check`)
      if(!checkItem) return
      if (type) {
        if (fixEl.scrollTop + fixEl.offsetHeight < checkItem.offsetHeight + checkItem.offsetTop+20) {
          fixEl.scrollTop = checkItem.offsetHeight + checkItem.offsetTop
        }
      } else {
        if (Math.abs(fixEl.scrollTop - checkItem.offsetTop) < checkItem.offsetHeight) {
          fixEl.scrollTop = checkItem.offsetTop-fixEl.offsetHeight+checkItem.offsetHeight
        }
        
      }
    },
    joinText() {
      let item = this.showOptions.find(item => item.check)
      if (this.isEnd) {
        this.text = this.text.replace(/[a-zA-Z]+$/, '')
        this.text += item.variableCode
      } else {
       let  beforeText = this.text.slice(0, this.cursorPos)
       let  afterText = this.text.slice(this.cursorPos) 
        beforeText = beforeText.replace(/[a-zA-Z]+$/, '') + item.variableCode
        this.text = beforeText + afterText
        setTimeout(() => {
          let textarea = document.querySelector(`#${this.id} textarea`)
          textarea.focus()
          textarea.selectionStart = textarea.selectionEnd= beforeText.length
        })
      }
      this.showOptions = []
      this.show = false
    },
    itemClick(item) {
      item.check = true
      this.joinText()
    },
    async getVariable() {
      let res = await queryVariableList({ formulaType: [1] })
      if (res) {
        this.options = res.map(item => { 
          return {
            variableCode: item.variableCode,
            variableName: item.variableName,
            check:false
          }
        })
      }
    }
 
  }
}

</script>
<style lang="less">
.auto-container {
  position: relative;
  .autoInput {
    width: 100% !important;
  }
  .fix-el {
    position: absolute;
    z-index: 9000;
    width: 250px;
    max-height: 200px;
    background-color: #fff;
    overflow-y: auto;
    box-shadow: 0px 1px 8px rgba(181, 176, 176, 0.3);
    .auto-item {
      padding-left: 5px;
      line-height: 1;
      padding: 10px;
      font-size: 14px;
      &.check {
        background-color: #D7A256;
        color: #fff;
      }
    }
  }

}
</style>

文章来源地址https://www.toymoban.com/news/detail-534982.html

到了这里,关于文本域输入提示,自动补全功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VScode代码自动补全提示

    打开设置 搜索 Suggest:Snippets Prevent Quick Suggestions ,去掉勾选 Ctrl+Shift+P打开setting.json文件,添加以下代码

    2024年02月11日
    浏览(42)
  • VSCode如何自动补全JavaScript代码

    在使用Visual Studio Code(以下简称VSCode)进行JavaScript开发时,自动补全功能是一项非常有用的功能。它可以帮助开发人员更快速地编写代码,减少拼写错误和语法错误的出现。本文将介绍如何在VSCode中启用和使用自动补全功能。 安装JavaScript插件 在开始之前,你需要确保已经安

    2024年02月03日
    浏览(41)
  • springboot集成elasticsearch,实现搜索提示补全功能

    注:在此之前需要下载elasticsearch以及拼音分词器。可以查看这篇文章,免费下载,下载完直接解压就行。 https://download.csdn.net/download/weixin_47874230/86514890 spring-data-elasticsearch版本需要与springboot版本对应,此处使用springboot版本为2.2.13.RELEASE

    2024年02月09日
    浏览(30)
  • VScode不能自动提示补全C代码

    之前使用source insight来编辑C代码,但是现在由于版权问题,公司不再允许使用,所以更换成免费的VScode。 VScode其实功能很强大,基本功能不亚于source insight,再辅以强大丰富的插件,可以说是一款非常好的代码编辑软件。 刚开始使用VScode发现一个很恼人的问题,就是很多代码

    2024年02月14日
    浏览(28)
  • input输入限制:自动补全两位小数、金额限制两位小数、只能输入正整数

    金额自动补全两位小数 限制只能输入正整数 金额限制两位小数 金额限制两位数,支持输入负数

    2024年04月17日
    浏览(27)
  • STM32CubeIDE 1.10.1 代码提示自动补全

    用习惯了Eclipse的开发者,用STM32CubeIDE很快就能上手,但遗憾的是安装了最新版本后,确没有代码自动补全功能,后来查找了很多资料,终于找到了一个可以自动补全代码提示的插件,亲测很好用。   使用方法如下: 在CubeIDE的安装路径STSTM32CubeIDE_1.9.0STM32CubeIDEplugins下找到

    2024年02月11日
    浏览(48)
  • 解决PyCharm下OpenCV没有自动补全、函数提示的问题!

    最近使用PyCharm编写一段需要使用Opencv库的代码,却发现cv2没有自动补全和函数提示了。博主自己找到以下解决办法,亲测有效!先做如下整理,以供参考! Control + R 打开运行,输入:cmd,调出命令行执行终端,并进入Python环境,执行下面两条指令,找到当前Python环境下的O

    2024年02月04日
    浏览(32)
  • Linux懒人神器:命令自动补全功能!

    在Linux中,命令自动补全功能是一种被广泛使用的懒人神器。它可以极大地提高命令行操作的效率和准确性。通过命令自动补全功能,用户只需输入部分命令或文件路径的片段,系统就能自动补全其余部分,甚至可以根据上下文提供合适的选项和参数。本文将详细解释Linux的命

    2024年02月09日
    浏览(46)
  • Cube IDE 实现自动代码补全功能

    总所周知,我们使用的 Cube IDE 虽然有代码自动补全功能,但是需要通过快捷键 alt + / 来激活代码补全功能,并不能很友好提高开发效率。但是,我们可以通过安装插件来实现自动代码补全功能,具体实现方式如下 测试环境使用的是 Cube IDE v1.11.2 版本 打开菜单栏上的 Help-Ins

    2024年02月03日
    浏览(42)
  • 使用JavaScript和Vue.js框架开发的电子商务网站,实现商品展示和购物车功能

    引言: 随着互联网的快速发展和智能手机的普及,电子商务行业正迎来一个全新的时代。越来越多的消费者选择网上购物,而不再局限于传统的实体店。这种趋势不仅仅是改变了消费者的习惯购物,也给企业带来了巨大的商机。为了不断满足消费者的需求,电子商务网站需要

    2024年02月15日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包