乐趣区

关于javascript:input-获取光标位置与设置光标位置

需要

输入框,反对 键盘输入 快捷按键 输出,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
退出移动版