高亮关键词替换
踩坑比较多,html的处理可能是之前不是接触很多。踩了一些坑,比如替换掉样式什么的, 现在直接贴出来给大家当个参考,
/***
* @description: 正则转义处理
* @param {String} string
* @return {String}
***/
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
/***
* @description: 高亮关键词
* @param {String} html html字符串
* @param {String} keyword 关键词
* @return {String}
***/
const changeContent = (html, keyword) => {
let index = 0;
if (
!keyword ||
typeof keyword !== 'string' ||
keyword.trim() === '' ||
/<\/?[a-z][\s\S]*>/i.test(keyword)
) {
console.error('Invalid searchText');
return html;
}
const escapedSearchText = escapeRegExp(keyword);
const regex = new RegExp(escapedSearchText, 'gi');
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
function processNode(node) {
if (node.nodeType === Node.TEXT_NODE) {
const fragment = document.createDocumentFragment();
let lastIdx = 0;
node.textContent.replace(regex, (match, idx) => {
const before = node.textContent.slice(lastIdx, idx);
const span = document.createElement('span');
span.className = 'keyword';
span.id = `specSpan${index++}`; // 这里添加index是为了搜索定位使用,可忽略
span.textContent = match;
fragment.appendChild(document.createTextNode(before));
fragment.appendChild(span);
lastIdx = idx + match.length;
});
fragment.appendChild(
document.createTextNode(node.textContent.slice(lastIdx))
);
node.parentNode.replaceChild(fragment, node);
} else if (node.nodeType === Node.ELEMENT_NODE) {
Array.from(node.childNodes).forEach(processNode);
}
}
Array.from(doc.body.childNodes).forEach(processNode);
return doc.body.innerHTML;
};
里面涉及到的知识点主要是DOMParser,平时可能不常用, 链接如下