<!-- 输入框 -->
<div class="infoAdd2">
<el-input
id="keywordsText"
ref="keywordsText"
v-model="addOrderMsgForm.content"
maxlength="500"
class="keywordsText"
resize="none"
type="textarea"
:rows="2"
placeholder="请输入内容,点击回车发送。"
:disabled="form.status !== 1"
@keyup.enter.native="addOrderMsgFun($event)"
@input="contentFun()"
@keydown.up.native="onkeydownFun"
@keydown.down.native="onkeydownFun"
@focus="foucsFun()"
>
</el-input>
</div>
<!-- @选择框 -->
<div v-if="urlListShow" class="urlList scroll">
<div class="ul">
<div
v-for="(item, k) in orderMsgMemberArrList"
:key="k"
:class="itemK == k ? 'li li0' : 'li'"
@mouseenter="mouseenterItemKFun(k)"
@click="setAtFun(1)"
>
{{ item.truename + ':' + item.username }}
</div>
</div>
</div>
js
mounted() {
document.onkeydown = this.showkey;// 监听按键
},
methods: {
showkey(event) {
let key = event.keyCode;
this.keyCode = key
let i = null
switch (key) {
case 37:// "按了←键!"
this.urlListShowFun('-')
break;
case 38:// "按了↑键!"
i = this.itemK - 1
this.itemK = i < 0 ? 0 : i
// this.itemK最小值只能0
break;
case 39:// "按了→键!"
this.urlListShowFun('+')
break;
case 40:// "按了↓键!"
i = this.itemK + 1
this.itemK = i == this.orderMsgMemberArrList.length ? this.orderMsgMemberArrList.length - 1 : i
// this.itemK最大值只能是卡选项的长度
break;
case 13:// "按了回车键!"
if (this.urlListShow == true) { // 可选项dom框打开时
this.setAtFun(0)
}
break;
}
},
/** 输入框内容变化 */
contentFun() {
if (this.urlListShow == true && this.keyCode == 13) {
// 按回车就不允许下一步判断,否弹出@选项框
return
}
this.urlListShowFun()
},
/** 移到可选人员上,修改选中项 */
mouseenterItemKFun(k) {
this.itemK = k
},
/** 写入选中@人信息 ,number==1是点击选中的*/
setAtFun(number) {
const index0 = this.$refs.keywordsText.$refs.textarea.selectionStart // 写入前的光标位置
setTimeout(() => {
if (this.checkarr.length > 0) { // 是模糊搜索打开的
let lastIndex = this.addOrderMsgForm.content.lastIndexOf('@', this.num)// 光标前的@位置
let txt = this.addOrderMsgForm.content.substring(0, lastIndex)
let index = this.$refs.keywordsText.$refs.textarea.selectionStart// 光标位置
let txt2 = this.addOrderMsgForm.content.substring(index)
// console.log(txt, JSON.stringify(txt2))
let item = this.orderMsgMemberArrList[this.itemK]
let atTxt = ` @${item.username} (${item.truename}) `
if (txt2.length == 0 || JSON.stringify(txt2) == JSON.stringify('\n')) {
this.addOrderMsgForm.content = txt + atTxt
} else {
console.log(JSON.stringify(txt2))
this.addOrderMsgForm.content = txt + atTxt + txt2
}
this.$nextTick(() => {
// 光标复位
let ctrl = this.$refs.keywordsText.$refs.textarea
console.log(ctrl.setSelectionRange)
// if (ctrl.setSelectionRange) {
ctrl.focus()
ctrl.setSelectionRange(index0 - 1 + atTxt.length, index0 - 1 + atTxt.length)
// } else if (ctrl.createTextRange) {
// console.log(2)
// var range = ctrl.createTextRange()
// range.collapse(true)
// range.moveEnd('character', index0)
// range.moveStart('character', index0)
// range.select()
// }
})
} else { // 非模糊搜索打开的
let index = this.$refs.keywordsText.$refs.textarea.selectionStart
let txt = this.addOrderMsgForm.content.substring(0, index - 2 + number)// 回车会多一个空格所以减去2,鼠标点击就是正常的所以+number,number就是1
let txt2 = this.addOrderMsgForm.content.substring(index)
console.log(txt, JSON.stringify(txt2))
let item = this.orderMsgMemberArrList[this.itemK]
let atTxt = ` @${item.username} (${item.truename}) `
if (txt2.length == 0) {
this.addOrderMsgForm.content = txt + atTxt
} else {
this.addOrderMsgForm.content = txt + atTxt + txt2
}
this.$nextTick(() => {
// 光标复位
let ctrl = this.$refs.keywordsText.$refs.textarea
console.log(ctrl.setSelectionRange)
// if (ctrl.setSelectionRange) {
ctrl.focus()
ctrl.setSelectionRange(index0 + atTxt.length, index0 + atTxt.length)
// } else if (ctrl.createTextRange) {
// console.log(2)
// var range = ctrl.createTextRange()
// range.collapse(true)
// range.moveEnd('character', index0)
// range.moveStart('character', index0)
// range.select()
// }
})
}
setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
this.urlListShow = false
this.checkarr = []
}, 200)
}, 0)
},
/** 是否弹出@候选列表框 */
urlListShowFun(val) {
let index = this.$refs.keywordsText.$refs.textarea.selectionStart// 光标所在位置
this.num = index
if (val == '-') { // 按了←键
this.num = this.num - 1 < 0 ? 0 : this.num - 1
} else if (val == '+') { // 按了→键
this.num = this.num + 1 > this.addOrderMsgForm.content.length ? this.addOrderMsgForm.content.length : this.num + 1
}
let typeTxt = this.addOrderMsgForm.content.substring(this.num - 1, this.num)// 拿光标前面两个字符
let lastIndex = this.addOrderMsgForm.content.lastIndexOf('@', this.num)
console.log(this.num, typeTxt, lastIndex)
if (typeTxt == '@' || JSON.stringify(typeTxt) == JSON.stringify('\n@')) {
// 光标在@和换行的@位置后面
this.itemK = 0// @选中位置
this.urlListShow = true
console.log('this.urlListShow1')
this.orderMsgMemberArrList = this.orderMsgMemberArr
} else if (lastIndex != -1) {
// 光标在非@后面时的前面发现@
let lastATtxt = this.addOrderMsgForm.content.substring(lastIndex + 1, this.num)// @符号后面:模糊搜索内容
this.checkarr = this.orderMsgMemberArr.filter((v) => (v.truename.includes(lastATtxt)))
// console.log(this.checkarr)
if (this.checkarr.length > 0) {
// 发现@后面内容跟聊天任意名字有模糊搜索相符的
this.orderMsgMemberArrList = this.checkarr// checkarr 模糊筛选的可选项, orderMsgMemberArrList 渲染的选项
this.itemK = 0// 当前@选中项
this.urlListShow = true
} else {
setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
this.urlListShow = false
this.checkarr = []
}, 200)
}
} else {
setTimeout(() => { // 加延时是避免回车时关闭了选择框,消息就发送出去了
this.urlListShow = false
this.checkarr = []
}, 200)
}
},
onkeydownFun(event) {
event.preventDefault(); // 禁止键盘上下按键时光标移动
},
}
css
.infoAdd2 {
padding-top: 8px;
flex: 1;
::v-deep {
.keywordsText {
overflow-y: hidden !important;
border: 1px solid #eee;
}
.el-textarea__inner {
border: 0;
}
}
}
.urlList {
position: absolute;
left: 0;
bottom: 61px;
background: #fff;
width: 100%;
padding-top: 5px;
max-height: 230px;
overflow-y: auto;
.ul {
.li {
padding: 3px 46px;
cursor: pointer;
}
.li0 {
background: #1026F1;
color: #fff;
}
}
}
网友评论