共计 2125 个字符,预计需要花费 6 分钟才能阅读完成。
需要
输入框,反对 键盘输入 与快捷按键 输出,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() 异步,所以加了 setTimeout
setTimeout(() => {
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
正文完
发表至: javascript
2023-01-04