如何使用React根据用户输入来突出显示文本? [英] How to highlight text based on user input with React?
问题描述
让我们简单地讨论一下带有 contenteditable ="true"
的准系统可编辑< div>
的简单情况:
Let's take the simple case of a barebones editable <div>
with contenteditable="true"
:
<div contenteditable="true">
Edit this
</div>
用户可以输入/编辑/删除
此< div>
元素的内容.
The user is able to input/edit/delete
the contents of this <div>
element.
对于某些输入形式,如果用户输入的文本大于字符数限制,则超过此限制的字符将被突出显示(警告用户停止添加文本).
For certain input forms, if the user inputs text greater than some limit of characters, the characters added over this limit will be highlighted (warning the user to stop adding text).
如何用React实现类似的目的?
How could I achieve something like this with React?
我认为< span>
可以用于突出显示文本,但是我无法概念化在达到字符数限制后如何开始突出显示.
I think <span>
could be used to highlight the text, but I cannot conceptualize how to begin the highlighting after the character count limit has been reached.
请让我知道问题是否明确.谢谢您的帮助.
Please let me know if the question is clear. Thank you for the help.
推荐答案
您可以通过签入 onchange
事件(div文本长度)来到达并用跨度包裹多余的文本,然后通过串联文本(不包含多余的字符)+包裹的多余文本跨度再次设置该div的内部html;
You could reach by checking in the onchange
event, the div text length
and wrap extra text by a span and set inner html of that div again by concatenatin text (without extra chars) + wrapped extra text span;
(由于xss注入,不建议使用innerHTML,但这是我发现的唯一解决方案)
这里的主要问题是一旦设置了div innerHTML,光标将停留在div文本的开头,因此我做了一些技巧,使用
that main problem here is once setting div innerHTML , your cursor will rest to start of div text , so i've done a little trick to set selection at the end of the text using
// get textt par before extra text
let start = html.slice(0, MAX_LENGTH ) ;
// get extra text
let overflow = html.slice(MAX_LENGTH) ;
// rap extra text by span
overflow = `<span style="color:${COLOR}">${overflow}</span>`;
//set text as innerHTML (or use dangerouslyINerHTML with sate var)
ref.current.innerHTML = start+overflow
// below part is to set cursor , at the end after inner html
// because innerHTML will reset selection to the start of div text
let range = document.createRange()
var sel = window.getSelection()
range.setStart(ref.current.lastChild, 1 )
sel.removeAllRanges()
sel.addRange(range)
请参见此处,使用带有特殊道具的snnipet示例创建了一个组件并使用了不同的道具
See here working snnipet with deiferent props example created a component and use different props
const { useRef } = React;
/* create Eitable Component */
const EditAbleDiv =( props ) => {
// get max length from props
const MAX_LENGTH = props.maxLength || 40;
// get color from props
const COLOR = props.warningColor || 'orange';
let ref = useRef(null);
// on change event
const contentChange = (e) => {
// get only text without html tags
let html = e.target.innerText;
if (html.length > MAX_LENGTH) {
// get textt par before extra text
let start = html.slice(0, MAX_LENGTH ) ;
// get extra text
let overflow = html.slice(MAX_LENGTH) ;
// rap extra text by span
overflow = `<span style="color:${COLOR}">${overflow}</span>`;
//set text as innerHTML (or use dangerouslyINerHTML with sate var)
ref.current.innerHTML = start+overflow
// below part is to set cursor , at the end after inner html
// because innerHTML will reset selection to the start of div text
let range = document.createRange()
var sel = window.getSelection()
range.setStart(ref.current.lastChild, 1 )
sel.removeAllRanges()
sel.addRange(range)
}
}
return <div ref={ref}
contentEditable
onInput={contentChange}
>
Edit text
</div>
}
/* end component */
function App() {
return (
<div>
<b> click in below div to edit text </b> <br/><br/>
<EditAbleDiv maxLength={25} />
<hr />
<EditAbleDiv maxLength={18} warningColor={"red"} />
<hr />
<EditAbleDiv maxLength={12} warningColor={"green"} />
</div>
)
}
ReactDOM.render(
<App />,
document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
这篇关于如何使用React根据用户输入来突出显示文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!