突出显示匹配的文本过滤器 javascript
Highlight matching text filter javascript
我正在做一个搜索过滤器突出显示。但它在替换值时呈现 [object Object]
而不是 <mark>match values</mark>
。
目前我有这个代码。
this.countries.response.filter((val) => {
const position = val.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
if (this.controls.country == "") {
return val;
} else if (position !== -1) {
return val;
}
}).map((e) => {
const position = e.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
let matches = e.value.substring(position, this.controls.country.length + position);
const regex = new RegExp(matches, 'gi');
const highlighted = e.value.replace(regex, '<mark>'+{matches}+'</mark>');
return (
<li class="lov-val list-group-item">
<p>{highlighted}</p>
</li>
)
})
我得到了这个输出。
我正在做这样的事情。
在不知道所有代码的情况下,我怀疑您只漏了一步。你得到一个 HTMLCollection。您必须重复此操作并将匹配项括起来 - 正如您已经正确完成的那样 - 用 mark.
这里有一个例子,让你更清楚。
const term = "c"
const countries = document.querySelectorAll("#countries div");
for(let i = 0; i < countries.length; i++) {
countries[i].innerHTML = countries[i].innerHTML.replace(new RegExp(term, "gi"), (match) => `<mark>${match}</mark>`);
}
<div id="countries">
<div class="item">USA</div>
<div class="item">China</div>
<div class="item">Canada</div>
</div>
<div id="output"></div>
您看到 [object Object]
是因为您使用 {matches}
将对象附加到字符串。你应该做类似 '<mark>' + matches + '</mark>'
的事情,这样你就可以附加一个字符串。
但是这可能无法解决问题。我怀疑您仍然会在输出中看到字符串 '<mark>EXAMPLE_TEXT</mark>'
,而不是实际的 html。这是因为包含有效 html 的文本内容只是被解释为文本,浏览器不会将其解析为 html.
看起来你在写 jsx
,所以我假设你正在使用 React。一个简单的解决方法是使用 dangerouslySetInnerHTML 道具。然而,使用它(因此是谨慎的名称)存在安全问题,因此请自行决定使用它。
我没有直接的替代方案,但我想应该有一些方法可以将每个国家/地区字符串分解成单独的部分,而不必使用 dangerouslySetInnerHTML
和正则表达式替换恶作剧。
例如
<span>
<span>
SOUTH
</span>
<mark>
AME // this is the part that's highlighted
</mark>
<span>
RICA
</span>
</span>
我正在做一个搜索过滤器突出显示。但它在替换值时呈现 [object Object]
而不是 <mark>match values</mark>
。
目前我有这个代码。
this.countries.response.filter((val) => {
const position = val.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
if (this.controls.country == "") {
return val;
} else if (position !== -1) {
return val;
}
}).map((e) => {
const position = e.value.toLowerCase().indexOf(this.controls.country.toLowerCase());
let matches = e.value.substring(position, this.controls.country.length + position);
const regex = new RegExp(matches, 'gi');
const highlighted = e.value.replace(regex, '<mark>'+{matches}+'</mark>');
return (
<li class="lov-val list-group-item">
<p>{highlighted}</p>
</li>
)
})
我得到了这个输出。
我正在做这样的事情。
在不知道所有代码的情况下,我怀疑您只漏了一步。你得到一个 HTMLCollection。您必须重复此操作并将匹配项括起来 - 正如您已经正确完成的那样 - 用 mark.
这里有一个例子,让你更清楚。
const term = "c"
const countries = document.querySelectorAll("#countries div");
for(let i = 0; i < countries.length; i++) {
countries[i].innerHTML = countries[i].innerHTML.replace(new RegExp(term, "gi"), (match) => `<mark>${match}</mark>`);
}
<div id="countries">
<div class="item">USA</div>
<div class="item">China</div>
<div class="item">Canada</div>
</div>
<div id="output"></div>
您看到 [object Object]
是因为您使用 {matches}
将对象附加到字符串。你应该做类似 '<mark>' + matches + '</mark>'
的事情,这样你就可以附加一个字符串。
但是这可能无法解决问题。我怀疑您仍然会在输出中看到字符串 '<mark>EXAMPLE_TEXT</mark>'
,而不是实际的 html。这是因为包含有效 html 的文本内容只是被解释为文本,浏览器不会将其解析为 html.
看起来你在写 jsx
,所以我假设你正在使用 React。一个简单的解决方法是使用 dangerouslySetInnerHTML 道具。然而,使用它(因此是谨慎的名称)存在安全问题,因此请自行决定使用它。
我没有直接的替代方案,但我想应该有一些方法可以将每个国家/地区字符串分解成单独的部分,而不必使用 dangerouslySetInnerHTML
和正则表达式替换恶作剧。
例如
<span>
<span>
SOUTH
</span>
<mark>
AME // this is the part that's highlighted
</mark>
<span>
RICA
</span>
</span>