提问人:Waseem Munir 提问时间:11/14/2023 最后编辑:Waseem Munir 更新时间:11/20/2023 访问量:109
检查用户是否在两个字符之间键入 textarea
check if user is typing between two characters textarea
问:
我有一个文本区域,默认情况下将包含任何类型的字符串,并且用户无法键入,除非他在左括号和右括号内键入,例如“Leave[]”我可以在括号内键入,但不能在括号外也可以嵌套,直到 n 级,例如 Leave[ Nested[ Test[] ],我想要一个函数来检查用户是否在括号内键入以返回否则true
false
const checkIfTypingBetweenBrackets=(prev:string,current:string):boolean =>{
// Code goes here
}
答:
-2赞
Akeel Ahmed Qureshi
11/14/2023
#1
输入状态使用方括号进行初始化。checkTyping 函数检查光标是否在方括号内,如果光标在方括号内,则忽略输入。
import React, { useState, useRef } from 'react';
const BracketText = () => {
const [input, setInput] = useState('[]');
const textareaRef = useRef(null);
const checkTyping = (text) => {
const { selectionStart, selectionEnd } = textareaRef.current;
return selectionStart > 0 && selectionEnd <= text.length - 1;
};
const handleChange = (e) => {
const currentValue = e.target.value;
if (checkTyping(currentValue)) {
setInput(currentValue);
}
};
return (
<div>
<textarea
ref={textareaRef}
value={input}
onChange={handleChange}
/>
</div>
);
};
export default BracketText;
评论
0赞
Akeel Ahmed Qureshi
11/20/2023
我已经更新了代码,也许对你有帮助。
1赞
Kaiido
11/14/2023
#2
如果我正确理解了这些要求,那么可以有嵌套括号的事实并不重要。重要的是最外层括号内的内容。
因此,我们能做的是在接收输入之前检查当前和位置,并将其与 a 的第一个索引和 a 的最后一个索引进行比较。
您还需要特别注意一些输入,例如退格键或前向删除,以便它们不会破坏最外层的括号:selectionStart
selectionEnd
<textarea>
[
]
const textarea = document.querySelector("textarea");
textarea.onbeforeinput = (evt) => {
const { selectionStart, selectionEnd, value } = textarea;
const bracketStart = value.indexOf("[");
const bracketEnd = value.lastIndexOf("]");
if (selectionStart <= bracketStart || selectionEnd > bracketEnd) {
evt.preventDefault();
}
if (evt.inputType === "deleteContentBackward" && selectionEnd === bracketStart + 1) {
evt.preventDefault();
}
if (evt.inputType === "deleteContentForward" && selectionStart === bracketEnd) {
evt.preventDefault();
}
// If you want to handle these ones, you'd need to measure the closest word and check if it's attached to your brackets.
if (evt.inputType === "deleteWordBackward" || evt.inputType === "deleteWordForward") {
evt.preventDefault();
}
}
<textarea>Leave[]</textarea>
注意:我没有对此进行广泛的测试,文本编辑是一个非常复杂的问题,因此可能有一些边缘情况是这个代码段无法处理的。
评论
0赞
James Hibbard
11/14/2023
这是我最初的想法,但似乎这里比检查最外层括号之间的内容更重要(参见 OP 的评论)。
0赞
Kaiido
11/14/2023
@JamesHibbard好吧......我不能 100% 确定这是他们所追求的,(此外,由于他们并没有真正响应,我希望向他们展示解决方案将有助于他们定义他们的问题),但从我所读到的内容来看,他们仍然处于“防止在括号外写作”的步骤。这个答案解决了这个问题。下一步是在调用 API 之前解析所有括号。但那将是另一个问题,这两个问题只是切线相关的。
0赞
James Hibbard
11/14/2023
绝对。FWIW,你的答案很好。我从中学到了一两个技巧。
0赞
Waseem Munir
11/14/2023
@Kaiido根据您的回答和评论,我把它弄出来了,我正在使用 ReactJS,所以那里会有所不同,我正在添加答案,所以如果有人需要,非常感谢
0赞
Waseem Munir
11/14/2023
#3
正如@Kaiido提到的,我不必担心嵌套括号,只需要关注最外层的括号,所以基于他的解决方案
随心所欲地编写以下函数
const checkIfTypingBetweenBrackets = (previousText, currentText) => {
let prevBracketOpen = previousText.indexOf("[");
let prevBracketClose = previousText.lastIndexOf("]");
let currentBracketOpen = currentText.indexOf("[");
let currentBracketClose = currentText.lastIndexOf("]");
if (
currentBracketClose - currentBracketOpen >
prevBracketClose - prevBracketOpen
) {
return true;
} else {
return false;
}
};
现在在将值保存为状态之前在 onChange 上使用它
<textarea
value={value}
onChange={(e) => {
// Here value argument is the previous value as we have not stored the latest value in state, and e.target.value is the latest value
let ifBetweenBrackets = checkIfTypingBetweenBrackets(
value,
e.target.value
);
// Only update the value in state if user is typing between brackets
if (ifBetweenBrackets) {
setValue(e.target.value);
}
}}
/>
下一个:大查询将字符串拆分为最常用的单词
评论
foo[]
foo[bar bla]
foo[bar] bla]
]
bla
bla]