Javascript 如何使用css突出显示两个文本的差异?

Javascript 如何使用css突出显示两个文本的差异?,javascript,jquery,html,css,Javascript,Jquery,Html,Css,我知道如何使用CSS突出显示文本的一部分: 现在我想强调两个字符串的区别。例如,给定以下两个字符串: 这是123号 及 那是124号 我需要像这里显示的那样突出显示一个文本。有人能帮我做到这一点吗 span.highlight{背景色:#B4D5FF} 这是123号 那是124号 “差异化”文本比乍一看要复杂得多。这完全取决于您想要检测每个差异的方式,但一般来说,您想要检测: 角色级别的更改(123对124) 增加文本(“我去过悉尼”与“我从未去过悉尼”) 删除文本(与上一示例相反) 棘

我知道如何使用CSS突出显示文本的一部分:

现在我想强调两个字符串的区别。例如,给定以下两个字符串:

这是123号

那是124号

我需要像这里显示的那样突出显示一个文本。有人能帮我做到这一点吗

span.highlight{背景色:#B4D5FF}
这是123号

那是124号

“差异化”文本比乍一看要复杂得多。这完全取决于您想要检测每个差异的方式,但一般来说,您想要检测:

  • 角色级别的更改(123对124)
  • 增加文本(“我去过悉尼”与“我从未去过悉尼”)
  • 删除文本(与上一示例相反)
棘手的一点是检测两个字符串之间的差异和共性。简单的实现可能只是逐个字符比较字符串。问题是,只要添加或删除一个字符,字符串的其余部分就会显示为差异,即使它实际上与原始文本相同


最好使用现有的扩散库。Javascript有很多优点。这个:看起来不错,不过对于你所需要的东西来说可能有些过分了。不过基本上-除非你想学习很多关于文本解析的知识,否则不要试图自己发明它

因此,您必须使用Javascript来完成这项工作,因为它涉及相当多的逻辑。正如在其他答案中提到的,检测文本中的差异比逐个字符检查要复杂一些

然而,出于好奇,我把这个天真的实现放在了一起:

下面是获取差异的函数的外观:

function getDiff(text1,text2){
  //Takes in two strings 
  //Returns an array of the span of the differences 
  //So if given:
  // text1: "that is number 124"
  // text2: "this is number 123"
  //It will return:
  // [[2,4],[17,18]]
  //If the strings are of different lengths, it will check up to the end of text1 
  //If you want it to do case-insensitive difference, just convert the texts to lowercase before passing them in 
  var diffRange = []
  var currentRange = undefined
  for(var i=0;i<text1.length;i++){
    if(text1[i] != text2[i]){
      //Found a diff! 
      if(currentRange == undefined){
        //Start a new range 
        currentRange = [i]
      }
    }
    if(currentRange != undefined && text1[i] == text2[i]){
      //End of range! 
      currentRange.push(i)
      diffRange.push(currentRange)
      currentRange = undefined
    }
  }
  //Push any last range if there's still one at the end 
  if(currentRange != undefined){
    currentRange.push(i)
    diffRange.push(currentRange)
  }
  return diffRange;
}
尝试更改代码笔中的文本,并观看其更新


一旦获得这些范围,它就会生成html并插入
标记,并将元素添加到页面中。如果你知道你的字符串总是一样的,这就足够了。否则,最好看看Javascript差异库!(似乎是一个很好的库)

您需要使用方法获取新字符串的所有字符,并迭代每个字符,并将其与旧字符串的字符进行比较

突出显示($(“#新”)、$(#旧”);
函数高亮显示(newElem,oldElem){
var oldText=oldElem.text(),
文本='';
newElem.text().split(“”).forEach(函数(val,i){
if(val!=oldText.charAt(i))
文本+=“”+val+“”;
其他的
text+=val;
});
html(文本);
}
。突出显示{背景色:#B4D5FF}

这是123号


这是数字124

当然,前面的答案是正确的,但是如果您有一个非常特定的格式可供比较,并且不想使用外部框架,可以使用类似的javascript对您的角色进行分组并使用css设置样式:

<html>

<style type="text/css">
.highlighted{
    background-color:blue;
}
</style>

<script type="text/javascript">

function init(){
    var output = document.getElementById("output");
    output.appendChild(highlightChanges("12777345aaaabbbbb","1277845abaababababababadsrfgadsg"));
}

var highlightChanges = function(str, compareStr){
    var strlength = str.length > compareStr.length ? compareStr.length : str.length;
    var allStr = document.createElement("span");
    var hl = null;
    var nohl = null;
    for(i = 0; i < strlength ; i++){
        if(str.charAt(i) != compareStr.charAt(i)){
            if(nohl != null){ 
                allStr.appendChild(nohl);
                nohl = null;
            }
            if(hl != null) hl.innerHTML += str.charAt(i);
            else{
                hl = document.createElement("span");
                hl.classList.add("highlighted");
                hl.innerHTML = str.charAt(i);
            } 
        }
        else{
            if(hl != null){
                allStr.appendChild(hl);
                hl = null;
            }
            if(nohl != null) nohl.innerHTML += str.charAt(i);
            else{
                nohl = document.createElement("span");
                nohl.innerHTML = str.charAt(i);
            } 
        }

        <!-- Fix by James Moberg to prevent premature end of comparison-->
        if(hl != null){
            allStr.appendChild(hl);
        } else if (nohl != null){
            allStr.appendChild(nohl);
        }
    }
    return allStr;
}
</script>

<body onload="init()">
    <div id="output"></div>
</body>

</html>

.突出显示{
背景颜色:蓝色;
}
函数init(){
var output=document.getElementById(“输出”);
输出.appendChild(高亮变化(“12777345aaaabbbbb”、“1277845ababababadsrfgadsg”);
}
var highlightChanges=函数(str、compareStr){
var strlength=str.length>compareStr.length?compareStr.length:str.length;
var allStr=document.createElement(“span”);
var-hl=null;
var nohl=null;
对于(i=0;i
我建议在网上搜索现有的库,因为这不是一个简单的问题。。。这是一个相当大的工作
这是数字124
文本是静态的还是来自其他地方,我的意思是来自
数据库
javascript
等等,你想突出显示字符串的哪一部分?@FastSnail有时会起作用。@M.Tanzil你是什么意思?这会影响解决方案吗?我喜欢你的答案如此简洁!我想用我的解决方案,你会有更少的标记,因为我的方法是查找范围,而不是为每个字符添加标记,但我喜欢它有多优雅@OmarShehata看到了跨度较小的新示例。感谢您提供的代码片段。就像我对奥马尔的回答所做的评论一样,如果我将“123”改为“12”,没有什么会突出显示,而我认为应该在这里突出显示一些内容来反映这一变化。似乎我必须使用diff库,正如大家所建议的:)@Meysam最好的方法是使用libary,但我回答了你的问题和你的示例。好的,我将你的答案标记为已接受:)谢谢你的代码示例。对于您的示例,有一点是,如果我将“123”更改为“12”,则不会突出显示任何内容,而我认为应该在此处突出显示某些内容以反映此更改:)正如我所说,只有当字符串长度相同时,此操作才有效。这就是为什么其他人建议你使用一个diff库来处理这样的删除:)你说得对,谢谢一个lotFYI:[4年
var text1 = "that is number 124"
var text2 = "this is number 123"
var diffRange = getDiff(text1,text2)
<html>

<style type="text/css">
.highlighted{
    background-color:blue;
}
</style>

<script type="text/javascript">

function init(){
    var output = document.getElementById("output");
    output.appendChild(highlightChanges("12777345aaaabbbbb","1277845abaababababababadsrfgadsg"));
}

var highlightChanges = function(str, compareStr){
    var strlength = str.length > compareStr.length ? compareStr.length : str.length;
    var allStr = document.createElement("span");
    var hl = null;
    var nohl = null;
    for(i = 0; i < strlength ; i++){
        if(str.charAt(i) != compareStr.charAt(i)){
            if(nohl != null){ 
                allStr.appendChild(nohl);
                nohl = null;
            }
            if(hl != null) hl.innerHTML += str.charAt(i);
            else{
                hl = document.createElement("span");
                hl.classList.add("highlighted");
                hl.innerHTML = str.charAt(i);
            } 
        }
        else{
            if(hl != null){
                allStr.appendChild(hl);
                hl = null;
            }
            if(nohl != null) nohl.innerHTML += str.charAt(i);
            else{
                nohl = document.createElement("span");
                nohl.innerHTML = str.charAt(i);
            } 
        }

        <!-- Fix by James Moberg to prevent premature end of comparison-->
        if(hl != null){
            allStr.appendChild(hl);
        } else if (nohl != null){
            allStr.appendChild(nohl);
        }
    }
    return allStr;
}
</script>

<body onload="init()">
    <div id="output"></div>
</body>

</html>