实现一个可以实时提示的textarea
Posted ฅ˙-˙ฅ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现一个可以实时提示的textarea相关的知识,希望对你有一定的参考价值。
该组件输入、换行、变换光标可以实时给出提示
效果:
textarea.vue
<template> <div> <el-input id="user-input" type="textarea" placeholder="请换行输入不同的通知用户" :autosize="{minRows: 2, maxRows: 10}" v-model="inputValue" @blur="closeHint" @input="settingHint" @click.native="settingHint" @keyup.native="disposeKey"> </el-input> <input-hint :all-items="hintItems" :position = \'hintPosition\' @select = "replaceStr" ></input-hint> </div> </template> <script lang="ts"> import { Vue, Component, Prop } from "vue-property-decorator"; import InputHint from "./inputHint.vue"; import $ from "jquery"; @Component({ components: { InputHint } }) export default class AdvancedTextarea extends Vue { inputValue: string = \'\'; Seprator = "\\n"; allUsers: string[] = []; hintItems: string[] = []; //传入提示框的项,可以是html字符串;为空则表示不显示提示框 initPosition = { //输入框的信息,用于计算提示框位置 left: 15, top: 5, rowHeight: 20, //一行的高度 fontSize: 7 //一个字的宽度 } hintPosition = { left: this.initPosition.left, top: this.initPosition.top } //按上下左右键时,重置提示框 disposeKey(e) { if (e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40) { this.settingHint(); } } settingHint(val?) { let cursorLocation = $(\'#user-input\').caret(); //光标位置 let newStr = this.inputValue.slice(0, cursorLocation); //输入框光标前的字符 let newArr = newStr.split(this.Seprator); let searchKey = newArr.length === 0 ? "" : newArr[newArr.length - 1]; let regExp = new RegExp(searchKey, \'ig\'); this.hintItems = searchKey ? this.allUsers.filter(item => item.indexOf(searchKey) !== -1).map(item => item.replace(regExp, `<strong>${searchKey}</strong>`)) : this.allUsers; this.hintPosition.left = this.initPosition.left + this.initPosition.fontSize * (searchKey.length > 0 ? searchKey.length - 1 : 0); this.hintPosition.top = this.initPosition.top + this.initPosition.rowHeight * (newArr.length > 10 ? 10 : newArr.length); } closeHint() { //延后关闭是因为立即关闭的话,点击提示框内容就无法触发点击事件 window.setTimeout(() => { this.hintItems = null; window.clearTimeout(); }, 200); } //将光标当前值替换为选中值 replaceStr(val) { let cursorLocation = $(\'#user-input\').caret(); //光标位置 let newStr = this.inputValue.slice(0, cursorLocation); //输入框光标前的字符 let row = newStr.split(this.Seprator).length - 1; //光标所在行 let oriArr = this.inputValue.split(this.Seprator); oriArr[row] = val; this.inputValue = oriArr.join(this.Seprator); $(\'#user-input\').focus(); } getAllUsers() { this.allUsers = [ \'xiaoming@qq.com\', \'daming@163.com\', \'liuxioawei@gridsum.com\', \'432454354@qq.com\', \'zhangzheng@qq.com\', \'mostlove@163.com\', \'wangweihao@gridsum.com\', \'67900332@qq.com\', \'xiaosi@qq.com\', \'loveshuang@163.com\', \'liuxioawei@gridsum.com\', \'87456563@qq.com\', \'yaru@qq.com\', \'wuyuetian@163.com\', \'junjun@gridsum.com\', \'67576889@qq.com\', \'shuanger@qq.com\', \'she@163.com\', \'ruiji@gridsum.com\', \'45454334@qq.com\', ] } mounted() { if (this.allUsers.length === 0) { this.getAllUsers(); } } } </script>
inputHint.vue
<template> <div v-show="allItems&&allItems.length!==0"> <ul class="el-dropdown-menu el-popper max-height new-scoll-bar" :style="{left: position.left+\'px\', top: position.top+\'px\'}"> <li class="el-dropdown-menu__item" v-for="(item,index) in allItems" :key="index" v-html="item" @click="selectItem(item)"></li> </ul> </div> </template> <style lang="postcss" scoped> .max-height { max-height: 250px; overflow-y: auto; } </style> <script lang="ts"> import { Vue, Component } from "vue-property-decorator"; @Component({ props: { allItems: { type: Array, default: [] }, position: { type: Object, default: { left: 0, top: 0 } } } }) export default class InputHint extends Vue { allItems = this.allItems; selectItem(item: string) { let regExp = /<strong>|<\\/strong>/g; let str = item.replace(regExp, \'\'); this.$emit(\'select\', str) } } </script>
以上是关于实现一个可以实时提示的textarea的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript 实现textarea限制输入字数, 输入框字数实时统计更新,输入框实时字数计算移动端bug解决