Skip to content Skip to sidebar Skip to footer

How To Highlight The Difference Of Two Texts With Css?

I know how to highlight part of a text with CSS using this script: span.highlight { background-color: #B4D5FF; } Now I want to highlight the difference of two strings. For exa

Solution 1:

You need to get all character of new string using split() method and iterate every character and compare it with character of old string.

highlight($("#new"), $("#old"));

functionhighlight(newElem, oldElem){ 
  var oldText = oldElem.text(),     
      text = '';
  newElem.text().split('').forEach(function(val, i){
    if (val != oldText.charAt(i))
      text += "<span class='highlight'>"+val+"</span>";  
    else
      text += val;            
  });
  newElem.html(text); 
}
.highlight {background-color: #B4D5FF}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><pid="old">this is number 123</p><pid="new">that is number 124</p>

Also you can use simpler code as shown in bottom

highlight($("#new"), $("#old"));

functionhighlight(newElem, oldElem){ 
  newElem.html(newElem.text().split('').map(function(val, i){
    return val != oldElem.text().charAt(i) ?
      "<span class='highlight'>"+val+"</span>" : 
      val;            
  }).join('')); 
}
.highlight {background-color: #B4D5FF}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><pid="old">this is number 123</p><pid="new">that is number 124</p>

And if you want to use less span check bottom code

highlight($("#new"), $("#old"));

functionhighlight(newElem, oldElem){ 
  var oldText = oldElem.text(),     
      text = '',
      spanOpen = false;  
  newElem.text().split('').forEach(function(val, i){  
    if (val != oldText.charAt(i)){   
      text += !spanOpen ? "<span class='highlight'>" : "";
      spanOpen = true;
    } else {       
      text += spanOpen ? "</span>" : "";
      spanOpen = false;  
    }  
    text += val;
  });
  newElem.html(text); 
}
.highlight {background-color: #B4D5FF}
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><pid="old">this is number 123</p><pid="new">that is number 124</p>

Solution 2:

So you'll have to use Javascript to accomplish this, since it involves a fair bit of logic. As mentioned in the other answer(s), detecting difference in text is a little bit more complicated than just checking character by character.

However, for curiosity's sake, I put together this naive implementation:

CodePen

Here's what the function that gets the differences looks like:

functiongetDiff(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 = undefinedfor(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;
}

The function getDiff takes in two strings, and returns the ranges at which they differ. This works great as long as the two strings are of the same length.

So to use this, all I do is:

var text1 = "that is number 124"var text2 = "this is number 123"var diffRange = getDiff(text1,text2)

Try changing the texts there in the CodePen and watch it update!

Once it gets these ranges, it then generates the html and inserts the <span> tags, and adds the element to the page. If you know your strings will always be the same, this could be enough. Otherwise, it would be best to look at a Javascript diff libary! (Jsdiff seems like a good library)

Solution 3:

'Diffing' text is more complicated than it might seem at first glance. It depends on exactly how you want to detect each difference, but in general, you want to detect:

  • changes at the character level (123 vs. 124)
  • Additions of text ('I have been to Sydney' vs. 'I have never been to Sydney).
  • Removal of text (reverse of previous example).

The tricky bit is detecting the differences and commonalities between the two strings. A naive implementation might just compare the strings character by character. The problem with that is, as soon as one character is added or removed, the rest of the string will appear as a difference, even though it's actually the same as the original text.

Your best bet is to use an existing diffing library. There are a lot out there for Javascript. This: https://github.com/kpdecker/jsdiff looks good, though it might be overkill for what you need. Basically though - don't try to invent this yourself unless you want to learn a lot about text parsing!

Solution 4:

Of course the previous answer is correct, but if you have a very specific format to compare against and don't want to use an external framework a javascript like this could be used to group your characters and style them with css:

<html><styletype="text/css">.highlighted{
    background-color:blue;
}
</style><scripttype="text/javascript">functioninit(){
    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 JamesMoberg to prevent premature end of comparison-->
        if(hl != null){
            allStr.appendChild(hl);
        } elseif (nohl != null){
            allStr.appendChild(nohl);
        }
    }
    return allStr;
}
</script><bodyonload="init()"><divid="output"></div></body></html>

Post a Comment for "How To Highlight The Difference Of Two Texts With Css?"