我正在使用JavaScript构建自动完成功能,需要在搜索时突出显示单词:
工作正常,但转义字符存在问题。
尝试突出显示包含转义字符的文本时(例如regex &>< example
),会发生以下情况:
Service Worker Typings to Supplement lib.webworker.d.ts
这种情况正在发生,因为我正在做以下事情:
element.innerHTML.replace(/a/g, highlight)
function highlight(str) {
return '<span class="foo"' + '>' + str + '</span>';
}
和innerHTML
包含单词&
,因此有意义。
总之,我需要一种解决方法,所以我想要一个功能:
a
和regex <br> example
并返回regex <br> ex<span class="foo">a</span>mple
r
和regex <br> example
并返回<span class="foo">r</span>egex <b<span class="foo">r</span>> example
<
和regex <br> example
并返回regex <span class="foo"><</span>br> example
答案 0 :(得分:1)
str.replace
仅返回带有预期替换的新字符串。原始字符串不变。
var str = 'replace me';
var str2 = str.replace(/e/g, 'E');
// For display only
document.write('<pre>' + JSON.stringify({
str: str,
str2: str2
}, null, 2) + '</pre>');
因此,代码需要将返回值从替换设置回所需的元素。
此外,innerHTML
将返回转义文本而非未转义文本。这可以在函数内部转义,但如果你可以使用textContent
,为什么还要麻烦。但是,在将高亮显示的文本设置为元素时使用innerHTML
,它将为我们自动转义文本。 :)
UPDATE :将值传递给函数,然后设置为元素:
注意:
lastIndex
higlightElemById('a', 'regex &>< example', 'a');
higlightElemById('b', 'regex &>< example', '&');
higlightElemById('c', 'regex <br> example', '<');
higlightElemById('d', 'regex <br> example', 'e');
higlightElemById('e', 'regex <br> example', '[aex]');
function higlightElemById(id, str, match) {
var itemElem = document.getElementById(id);
// minimal regexp escape to prevent shenanigans
var safeMatch = match.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// construct regexp to match highlight text
var regexp = new RegExp('(.*?)(' + safeMatch + ')', 'g');
var text = '';
var lastIndex;
var matches;
while (matches = regexp.exec(str)) {
// Escape the non-matching prefix
text += escapeHTML(matches[1]);
// Highlight the match
text += highlight(matches[2]);
// Cache the lastIndex in case no regexp at end
lastIndex = regexp.lastIndex;
}
if (text) {
text += escapeHTML(str.substr(lastIndex));
} else {
text += escapeHTML(str);
}
itemElem.innerHTML = text;
}
function highlight(str) {
return '<span class="myHighlightClass">' + str + '</span>';
}
function escapeHTML(html) {
this.el = this.el || document.createElement('textarea');
this.el.textContent = html;
return this.el.innerHTML;
}
.myHighlightClass {
text-decoration: underline;
color: red;
}
<div id="a"></div>
<div id="b"></div>
<div id="c"></div>
<div id="d"></div>
<div id="e"></div>