Я создаю поисковую систему и хочу изменить цвет совпадающих символов
Я использую регулярное выражение для сопоставления входного значения с элементами массива, я искал решение проблемы с подсветкой и нашел это: item.replace(regex, '<mark>$1</mark>'), но я не знаю, как это реализовать.
onTextChange = (e) => {
const value = e.target.value;
let suggestions = [];
if (value.length > 0) {
const regex = new RegExp(`${value}`, 'i');
suggestions = this.items.sort().filter(v => regex.test(v));
this.setState(() => ({ suggestions, textValue: value }));
}
this.setState(() => ({ suggestions, textValue: value }));
}
//this function return autosuggestion list
renderSuggestions () {
const {suggestions} = this.state;
if (suggestions.length !== 0) {
//suggestionSelected() hidden suggestion list after clicking
return(
<div className = "auto-suggestions">
<ul>
{suggestions.map((item) =>
<li key = {item} className = "suggestion-item" onClick = {()=>
this.suggestionSelected(item)}>{item}</li>)}
</ul>
</div>
);
}
}
//within the render() I have:
const {suggestions, textValue} = this.state;
<div className = "container">
<input type = "text" onChange = {this.onTextChange} value= {textValue} />
{this.renderSuggestions()}
{this.showUsers()}
</div>
Я не уверен, где и как можно решить эту проблему, любая помощь приветствуется.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам нужно отобразить выделенный текст в виде простого html, вы можете получить этот образец
safeHTML(item) {
return item.replace(new RegExp(this.state.selectedText, 'gi'),'<strong>$&</strong>')
}
getHighlighted(item){
return (
<p key = {item}
dangerouslySetInnerHTML = {{
__html : this.safeHTML(item)
}} />
)
}
render() {
return <div>
{
this.state.suggestions.map(s => {
return this.getHighlighted(s)
})
}
</div>;
}
PS: вам нужны очищенные данные для безопасности
Надеюсь, это поможет :)
У вас есть 2 проблемы, которые необходимо решить: (1) извлечь соответствующую подстроку в suggestions и (2) выделить соответствующую подстроку в пользовательском интерфейсе.
Вы можете использовать String.prototype.split вместо RegExp.prototype.test, чтобы разделить строку с помощью соответствующего регулярного выражения и подготовить необходимые данные для рендеринга:
onTextChange = (e) => {
const value = e.target.value;
let suggestions = [];
if (value.length > 0) {
const regex = new RegExp(`${value}`, 'i');
suggestions = this.items.sort().map(v => {
const arr = v.split(regex);
return arr.map(substr => ({
value: substr,
isMatched: regex.test(substr)
}))
});
suggestions = suggestions.filter(arr => arr.some(({ isMatched}) => isMatched))
this.setState(() => ({ suggestions, textValue: value }));
}
this.setState(() => ({ suggestions, textValue: value }));
}
затем распечатайте список предложений:
renderSuggestions () {
const {suggestions} = this.state;
if (suggestions.length !== 0) {
return(
<div className = "auto-suggestions">
<ul>
{suggestions.map((item) =>
<li key = {item} className = "suggestion-item" onClick = {()=>
this.suggestionSelected(item)}>
{item.map(({ value, isMatched}) =>
{isMatched ?
<span>{value}</span> :
<strong>{value}</strong>
}
)}
</li>)}
</ul>
</div>
);
}
}
это отличный способ, теперь он отлично работает. Большое спасибо