需要
输入框,反对键盘输入与快捷按键 输出,UI 如下「基于antd」:
关键点:键盘输入间接应用 input onChange 事件即可,快捷按键输出须要依据光标地位插入,插入后光标在新插入的字符后。
解决方案
获取 input 光标地位
通过 element.selectionStart
获取光标地位。
const inputDom = document.getElementById("input")const selectionStart = inputDom.selectionStart
如图,此时的 selectionStart 是 3。
设置 input 光标
通过 element.setSelectionRange()
设置光标地位,前提是 input 被 focus。
inputDom.focus()// focus() 异步,所以加了 setTimeoutsetTimeout(() => { const nextSelection = selectionStart + 1 inputDom.setSelectionRange(nextSelection, nextSelection)}, 0)
element.setSelectionRange 语法
element.setSelectionRange(selectionStart, selectionEnd [, selectionDirection]);
- selectionStart: 被选中的第一个字符的地位索引, 从 0 开始。如果这个值比元素的 value 长度还大,则会被看作 value 最初一个地位的索引。
- selectionEnd: 被选中的最初一个字符的下一个地位索引。如果这个值比元素的 value 长度还大,则会被看作 value 最初一个地位的索引。
- selectionDirection:抉择方向。forward/backward/none
如果 selectionStart 与 selectionEnd 雷同,不选中任何,光标汇集在 selectionStart/selectionEnd。
如果 selectionEnd 小于 selectionStart,不选中任何,光标汇集在在 selectionEnd。
inputDom.setSelectionRange(0, 4)
体现如下图:
残缺代码
import React, { useState, useRef } from 'react'import { throttle } from 'lodash'import { Input, Button, Tag } from 'antd'const SHORTCUT = [0, '*', '#', 9]const InputPro = () => { const [value, setValue] = useState('') const inputRef = useRef() const handleSubmit = throttle(() => { console.log('value', value) }, 3000) const handleInputChange = e => { setValue(e.target.value?.trim()) } const handleTagChange = val => { const inputDom = inputRef.current?.input || {} let selectionStart = inputDom.selectionStart if (typeof selectionStart !== 'number') { selectionStart = value.length } const data = `${value.slice( 0, selectionStart, )}${val}${value.slice(selectionStart)}` if (data.length <= 25) { setValue(data) inputDom.focus() setTimeout(() => { const nextSelection = selectionStart + 1 inputDom.setSelectionRange(nextSelection, nextSelection) }, 0) } } return ( <div> <Input.Group compact> <Input allowClear style={{ width: 160 }} maxLength={25} placeholder='请输出' value={value} onChange={handleInputChange} ref={inputRef} /> <Button type='primary' onClick={handleSubmit} disabled={value.length === 0} > 确认 </Button> </Input.Group> <div style={{ display: 'flex', alignItems: 'center', marginTop: 8 }}> {SHORTCUT.map(itm => ( <div key={itm} onClick={() => handleTagChange(itm)}> <Tag color="#108ee9">{itm}</Tag> </div> ))} </div> </div> )}export default InputPro