我在React有一个textarea,我想变成一个"记事本"。这意味着我想要"标签"缩进的关键而不是无焦点。我查看了this answer,但我无法与React合作。这是我的代码:
handleKeyDown(event) {
if (event.keyCode === 9) { // tab was pressed
event.preventDefault();
var val = this.state.scriptString,
start = event.target.selectionStart,
end = event.target.selectionEnd;
this.setState({"scriptString": val.substring(0, start) + '\t' + val.substring(end)});
// This line doesn't work. The caret position is always at the end of the line
this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1;
}
}
onScriptChange(event) {
this.setState({scriptString: event.target.value});
}
render() {
return (
<textarea rows="30" cols="100"
ref="input"
onKeyDown={this.handleKeyDown.bind(this)}
onChange={this.onScriptChange.bind(this)}
value={this.state.scriptString}/>
)
}
当我运行此代码时,即使我按下&#34;标签&#34;键盘中间的键,我的光标总是出现在字符串的末尾。任何人都知道如何正确设置光标位置?
答案 0 :(得分:23)
在状态更新后,您必须更改光标位置(setState()
不会立即变异this.state
)
为了做到这一点,你必须在函数中包装this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1;
并将其作为第二个参数传递给setState
(回调)。
handleKeyDown(event) {
if (event.keyCode === 9) { // tab was pressed
event.preventDefault();
var val = this.state.scriptString,
start = event.target.selectionStart,
end = event.target.selectionEnd;
this.setState(
{
"scriptString": val.substring(0, start) + '\t' + val.substring(end)
},
() => {
this.refs.input.selectionStart = this.refs.input.selectionEnd = start + 1
});
}
}
答案 1 :(得分:4)
对于任何寻求快速React Hooks(16.8+)光标位置示例的人:
import React { useRef } from 'react';
export default () => {
const textareaRef = useRef();
const cursorPosition = 0;
return <textarea
ref={textareaRef}
onBlur={() => textareaRef.current.setSelectionRange(cursorPosition, cursorPosition)}
/>
}
在此示例中,当输入不再聚焦时,使用setSelectionRange
将光标位置设置为cursorPosition
的值。
答案 2 :(得分:0)
这是一个挂钩风格的体系结构中的解决方案。我的建议是在插入标签时立即更改文本区域value
和selectionStart
。
import React, { useRef } from "react"
const CodeTextArea = ({ onChange, value, error }) => {
const textArea = useRef()
return (
<textarea
ref={textArea}
onKeyDown={e => {
if (e.key === "Tab") {
e.preventDefault()
const { selectionStart, selectionEnd } = e.target
const newValue =
value.substring(0, selectionStart) +
" " +
value.substring(selectionEnd)
onChange(newValue)
if (textArea.current) {
textArea.current.value = newValue
textArea.current.selectionStart = textArea.current.selectionEnd =
selectionStart + 2
}
}
}}
onChange={e => onChange(e.target.value)}
value={value}
/>
)
}
答案 3 :(得分:0)
在@Configuration
public class XsltConfiguration {
@Bean
@Qualifier("XslA")
XsltExecutable getXsltExecutableA() {
XsltCompiler compiler = new Processor(true).newXsltCompiler();
//load xsl ...
return compiler.compile(xslSource);
}
@Bean
@Qualifier("XslB")
XsltExecutable getXsltExecutableB() {
XsltCompiler compiler = new Processor(true).newXsltCompiler();
//load xsl ...
return compiler.compile(xslSource);
}
}
中,最佳选择是这样的:
React 15
您可以通过class CursorForm extends Component {
constructor(props) {
super(props);
this.state = {value: ''};
}
handleChange = event => {
// Custom set cursor on zero text position in input text field
event.target.selectionStart = 0
event.target.selectionEnd = 0
this.setState({value: event.target.value})
}
render () {
return (
<form>
<input type="text" value={this.state.value} onChange={this.handleChange} />
</form>
)
}
}
和event.target.selectionStart
值完全控制光标位置,而无需访问实际的DOM树。