2013-03-29 31 views
16

我的jQuery“比较”函数有一些问题。其任务是比较两个文本区域并突出差异。比较两个客户端键入的文本字段jQuery

例如。 “我的名字是迈克尔”在一个文本区域,而“我的名字是米歇尔”在另一个文本区域。

我的函数将返回两个输入并突出显示第一个输入中的字符“a”,并突出显示第二个输入中缺少的字符。

这是功能看起来如何,但它似乎并没有100%的时间工作。

$(function() { 

$('#btnCompare').on('click', function() { 
    compare(); 
}); 

function compare() { 
    $('#divColLeft').empty(); 
    $('#divColRight').empty(); 
    var textOne = $('#taOneComp').val(); 
    var textTwo = $('#taTwoComp').val(); 

    var output; 
    var outputX; 

    var arrTextOne = []; 
    var arrTextTwo = []; 

    for (var i = 0; i < textOne.length; i++) { 
     output = textOne.charAt(i); 
     arrTextOne.push(output); 
    } 
    for (var x = 0; x < textTwo.length; x++) { 
     outputX = textTwo.charAt(x); 
     arrTextTwo.push(outputX); 
    } 

    $.each(arrTextOne, function (y, e) { 
     if ($.inArray(e, arrTextTwo) == -1) { 
      $('#divColLeft').append(e); 
      $('#divColLeft').highlight(e); 
     } else { 
      $('#divColLeft').append(arrTextOne[y]); 
     } 
    }); 

    $.each(arrTextTwo, function (z, f) { 
     if ($.inArray(f, arrTextOne) == -1) { 
      $('#divColRight').append(f); 
      $('#divColRight').highlight(f); 
     } else { 
      $('#divColRight').append(arrTextTwo[z]); 
     } 
    }); 
} 

}); 

更新:为了更加精确,提高了原来的问题

如果某些模块主要包括炭“一”之前的任何两个文本的,这是应该强调的差异。在第一个文本中,应该突出显示“a”,在第二个文本中我想输入突出显示差异的空白空间(缺少的字符)。

+2

您可能想要查看http://code.google.com/p/google-diff-match-patch/ – codelove

+1

您认为该函数应该:“突出显示第二个字符中缺少的字符” 。你如何突出缺失的东西?你会插入一个空格字符在那个位置,然后突出显示? – Floremin

+0

我过去几天看起来非常相似,并且发现[jsdiff](http://ejohn.org/projects/javascript-diff-algorithm/)对我来说非常合适。显示其工作的示例是[此链接](http://blog.djsipe.com/js-diff/)。 – Fergus

回答

6

您的代码将只工作如果两个字符串具有完全相同的长度和相同的字排列,否则会打破也就是说,如果您在测试字符串的开头添加一个额外的字符。
一些编码我设法想出下面的代码后,它比较两个字符串,并找到失踪charcters /话,多余的字符/单词和错误拼写:

function compare() { 
    var elm1 = document.getElementById("div1"), 
     elm2 = document.getElementById("txt"), 
     output = document.getElementById("div2"), 
     txt1 = elm1.innerHTML,   //original text 
     txt2 = elm2.value,    //submitted text 
     arr1 = txt1.split(" "),   //split original text to array of words 
     arr2 = [];      //miss matching words will be added here 

//filter txt1 and txt2 from matching words and add miss matching to arr2/////// 
    for (var i in arr1) { 
     var match = txt2.match(new RegExp("\\b" + arr1[i] + "\\b")); 
     if (match) { 
      txt2 = txt2.replace(new RegExp("\\s?" + arr1[i]), ""); 
      txt1 = txt1.replace(new RegExp("\\s?" + arr1[i]), ""); 
     } else if (!match) { 
      arr2.push(arr1[i]); 
     } 
    } 
//compare miss matching words from original and submitted text, if matching charachters is more that 50% highlight missing and extra characters 
    var arr3 = txt2.split(" "), //convert filtered submitted text to words array 
     right = elm1.innerHTML, 
     wrong = elm2.value; 
    for (var a in arr2) { 
     for (var b in arr3) { 
      var match2 = arr3[b].match(new RegExp("[" + arr2[a] + "]", "g")), 
       t = (arr2[a].length > arr3[b].length) ? arr2[a].length : arr3[b].length; 
      if (match2 && match2.length >= t * 0.5) { //check for words that look similar 
       txt2 = txt2.replace(new RegExp("\\s?" + arr3[b]), ""); 
       txt1 = txt1.replace(new RegExp("\\s?" + arr2[a]), ""); 
       var str1 = "", 
        str2 = "", 
        n = 0; 
       for (var c = 0; c < t; c++) { 
        if (arr2[a].charAt(c) === arr3[b].charAt(c + n)) { 
         str1 += arr3[b].charAt(c + n); 
         str2 += arr2[a].charAt(c); 
        } else if (arr2[a].charAt(c) !== arr3[b].charAt(c + n)) { 
         if(arr2[a].charAt(c + 1) == arr3[b].charAt(c + n)){ 
          str2 += arr2[a].charAt(c).fontcolor("blue"); 
          str1 += "_".fontcolor("red"); 
          n--; 
         }else if(arr2[a].charAt(c) == arr3[b].charAt(c + n + 1)){ 
          str1 += arr3[b].charAt(c + n).fontcolor("orange"); 
          n++; 
          c--; 
         }else{ 
          str1 += arr3[b].charAt(c + n).fontcolor("red"); 
          str2 += arr2[a].charAt(c).fontcolor("green"); 
         } 
        } 
       } 
       wrong = wrong.replace(arr3[b], str1); 
       right = right.replace(arr2[a], str2); 
      } 
     } 
    } 
//check for extra words////////////////////////////////////// 
    extra = txt2.split(" "); 
    for(var d in extra){ 
     wrong = wrong.replace(extra[d], extra[d].fontcolor("grey")); 
    } 
//check for missing words////////////////////////////////////// 
    missing = txt1.split(" "); 
    for(var f in missing){ 
     right = right.replace(missing[f], missing[f].fontcolor("blue")); 
    } 
    output.innerHTML = wrong; 
    elm1.innerHTML = right; 
} 

DEMO

它如何工作:

  1. 比较原始的,并提交文字和寻找匹配的词,并删除它们
  2. 从两个串
  3. 比较剩余的话如果两个单词看起来相似(等于字符总字符=> 50%)
  4. 检查缺少/额外/拼错字符和突出显示它们。
  5. 从两个字符串中删除拼写错误的单词
  6. 突出显示原文剩下的词作为漏字
  7. 突出显示提交的文字剩余的词作为多余的话
+0

太棒了。但我看到一个问题,你应该添加更多的东西,检查这个评论http://stackoverflow.com/questions/15706827/compare-two-client-typed-text-fields-jquery#comment22417689_15706827 –

+0

伟大的我会测试这个代码今天晚些时候,正如@KonradGadzina所说。如果其中一个在两个文本中的任何一个之前包含“a”,则这是应该突出显示的区别。在第一个文本中,应该突出显示“a”,在第二个文本中我想输入突出显示差异的空白空间(缺少的字符)。还更新了我原来的帖子。 – rickard

+0

完成后,我认为最好是添加“_”来表示缺少的字符,而如果你希望它是一个空间,我可以改变它。请参阅我的演示 – razzak

-1
$(document).ready(function() { 

    $('#btnCompare').on('click', function() { 
     compare(); 
    }); 

    function compareText(textOne, textTwo) 
    { 
     var len = Math.min(textOne.length, textTwo.length); 
     for (var i=0;i<len; i++) 
     { 
      if (textOne.charAt(i) == textTwo.charAt(i)) continue; 

      return i;  // this character is different 
     } 

     if (textOne.length == textTwo.length) return -1; // same 

     return i; 
    } 

    function compare() { 
     $('#divColLeft').empty(); 
     $('#divColRight').empty(); 
     var textOne = $('#taOneComp').val(); 
     var textTwo = $('#taTwoComp').val(); 

     var diffIndex = compareText(textOne, textTwo); 
     if (diffIndex == -1) 
     { 
      // TODO: tell user they are identical 
      $('#divColLeft').html('Identical'); 

     } else { 

      // if textTwo has more characters, 
      // add a dummy character for highlighting to textOne 

      if (diffIndex >= (textOne.length)) textOne += '_'; 

      var char = textOne.charAt(diffIndex); 

      // highlight differing character 

      var tmpLeft = textOne.substring(0, diffIndex); 
      tmpLeft += "<span style='background-color:yellow;font-weight:bold'>" + char + "</span>"; 
      tmpLeft += textOne.substring(diffIndex+1); 

      $('#divColLeft').html(tmpLeft); 
     } 
    } 
}); 
+0

这周末我会看看这个答案。现在在度假。在此先感谢 – rickard

+0

嗯,这不是一个非常广泛的解决方案。如果有人添加了一个额外的字母怎么办然后,这个角色后面的所有内容都将无法匹配,尽管这是一个小小的区别。 –

0

我的代码比较第一textarea的话第二textare words.For示例..第一textarea文本是'你好吗'和第二textarea文本是'我很好'。它会比较'如何'与'我'和'是'与'我'。 请尝试此代码...我的fiddle

$(function() { 

      $('#btnCompare').on('click', function() { 
       compare(); 
       return false; 
      }); 

      function compare() { 
       $('#divColLeft').empty(); 
       $('#divColRight').empty(); 

       var textOne = $.trim($('#taOneComp').val()); 
       var textTwo = $.trim($('#taTwoComp').val()); 

       var TempArr1 = textOne.split(' '); 
       var TempArr2 = textTwo.split(' '); 
       var arr1 = []; 
       for (var i = 0; i < TempArr1.length; i++) { 
        if (TempArr1[i] !== "" && TempArr1[i] !== null) { 
         arr1.push(TempArr1[i]); 
        } 
       } 

       var arr2 = []; 
       for (var i = 0; i < TempArr2.length; i++) { 
        if (TempArr2[i] !== "" && TempArr2[i] !== null) { 
         arr2.push(TempArr2[i]); 
        } 
       } 
       var minArrLen = arr1.length < arr2.length ? arr1.length : arr2.length; 

       for (var x = 0; x < minArrLen; x++) { 

        var maxCharLen = arr1[x].length > arr2[x].length ? arr1[x].length : arr2[x].length; 
        for (var y = 0; y < maxCharLen; y++) { 
         if (arr1[x].charAt(y) == ' ') { 
          $('#divColLeft').append('<span class="missing">' + arr2[x].charAt(y) + '</span>'); 

          $('#divColRight').append('<span class="missmatch">' + arr2[x].charAt(y)) + '</span>'; 
         } 
         else if (arr2[x].charAt(y) == ' ') { 
          $('#divColLeft').append('<span class="missing">' + arr1[x].charAt(y) + '</span>'); 

          $('#divColRight').append('<span class="missmatch">' + arr1[x].charAt(y)) + '</span>'; 
         } else if (arr1[x].charAt(y) == arr2[x].charAt(y)) { 
          $('#divColLeft,#divColRight').append(arr1[x].charAt(y)); 
         } 
         else { 
          $('#divColLeft').append('<span class="missmatch">' + arr1[x].charAt(y) + '</span>'); 
          $('#divColRight').append('<span class="missing">' + arr2[x].charAt(y) + '</span>'); 
         } 
        } 
        $('#divColLeft').append(' '); 
        $('#divColRight').append(' '); 
       } 

       if (minArrLen < arr1.length) { 
        for (var Len = minArrLen; Len < arr1.length; Len++) { 
         $('#divColLeft').append(arr1[Len]) 
             .append(' '); 
        } 
       } else if (minArrLen < arr2.length) { 
        for (var Len = minArrLen; Len < arr2.length; Len++) { 
         $('#divColRight').append(arr2[Len]) 
             .append(' '); 
        } 
       } 
      } 
     }); 
+0

如果您在第二个输入的开始添加额外的单词或字符,您的代码将中断。尝试“这是一个测试”和“这是一个测试”。 – razzak

+0

我写了编码来比较单词......假设我们给“这是一个测试”和“这是一个测试”......它会将它与一个.. –

+0

嗯这不是什么OP我想,它提到“它的使命是比较两个文本区域并突出差异”。 – razzak