非常感谢回复的人。我有趣地找到了一个解决方案。希望这可以帮助其他人解决这个问题。
这个概念是我有两个带有内容的可编辑文本框,我强调了两者之间的区别。首先,让我们解决突出显示的问题。这很简单。我使用了 Squiggs 的方法,通过使用以下包来比较两个字符串:
https://github.com/kpdecker/jsdiff
利用Diff包,我创建了一个比较两个字符串并返回结果的函数:
function compareStrings(string1, string2) {
let results = Diff.diffChars(string1, string2);
let output = "";
results.forEach((item) => {
if (item.removed) {
output += `<span style="background-color:yellow">${item.value}</span>`;
} else if (!item.added) {
output += `${item.value}`;
}
});
return output;
}
在使用Diff 包时,它将识别出的差异和相似之处分成不同的项目。它使处理结果变得相对容易。在上面的代码中,results 中的结果被迭代。如果一个项目将removed 设置为true,则它是string1 中的一个项目,而不是string2。如果 added 设置为 true,则它是 string2 中的一个项目,而不是 string1。如果两者都没有设置为 true,则它是两个字符串中的一个项目。我的函数的输出将包含string1 的所有字符。如果某个项目将added 设置为true,则忽略该项目。例如,如果string1 是cat,string2 是bat,则output 将是cat,但c 以黄色突出显示。
那么如何将这个突出显示的文本插入到 Material-Ui 文本框中?好吧,我选择了使用 contentEditable 控件的路线。您可以将 p 标记(和其他标记)转换为呈现 HTML 的可编辑文本框。这不是我喜欢的解决方案,因为它带来了处理 XSS 的麻烦,但这似乎是不可避免的。如果有人遵循此解决方案,我恳请您实施客户端和服务器端输入清理以防止 XSS。后者尤其重要,因为可以通过各种方法轻松绕过客户端验证,例如使用检查元素修改页面或使用数据包制作工具。
以下是 HTML 中 contentEditable 文本框的外观:
<p
id="textbox1"
className="textbox"
variant="outlined"
contentEditable={true}
/>
从这里,我可以将compareStrings 的结果分配给它:
document.getElementById("textbox1").innerHTML = htmlData
所以最终结果将有两个 contentEditable 文本框。我将不得不调用 compareStrings 两次并将结果应用于两者。
当然,我只详细介绍了解决此问题的要点。还有其他生活质量功能,例如复制和粘贴,详情如下:
Highlight value of @material-ui/core TextField in React at specific indices