原生JS實戰開發同步翻譯(附源代碼)

1. 背景:

平時不知道用js寫什麼練手,這裏就寫了一個類似百度翻譯的小demo。大家可以平時沒事兒了看看書,寫寫像這種類型的小demo,調用以下公開的api即可。對於學生黨,能進入學校實驗室做項目更好。進不去的,平時寫寫小demo練練也不差。(我爲什麼沒在實驗室)

2. demo前準備工作:

  1. 頁面佈局

  2. 瞭解百度翻譯API,所需配置參數

  3. 準備 MD5.js 加密算法函數(百度自己搜)

  4. 寫js代碼

3. 步驟:

1. 頁面佈局:佈局就不說了,直接貼圖上代碼:

可進行語言切換

html代碼


 
  1. <!DOCTYPE html>

  2. <html>

  3. <head>

  4.  <meta charset="utf-8">

  5.  <title></title>

  6.  <link rel="stylesheet" type="text/css" href="css/style.css">

  7. </head>

  8. <body>

  9.  <div id="main">

  10.    <div class="left">

  11.      <div class="title">

  12.        要翻譯爲:

  13.        <span class="lang">英文</span>

  14.        <ul class="ul1">

  15.          <li data-lang="en">英語</li>

  16.          <li data-lang="zh">中文</li>

  17.          <li data-lang="jp">日語</li>

  18.          <li data-lang="kor">韓語</li>

  19.          <li data-lang="fra">法語</li>

  20.          <li data-lang="ru">俄語</li>

  21.          <li data-lang="de">德語</li>

  22.        </ul>

  23.      </div>

  24.      <textarea class="text" placeholder="要翻譯的單詞/句子" value=""></textarea>

  25.    </div>

  26.    <div class="right">

  27.      <div class="title">翻譯結果:</div>

  28.      <div class="cont"></div>

  29.    </div>

  30.    <div class="bottom">

  31.      <button class="reset">清除</button>

  32.      <button class="trans">翻譯</button>

  33.    </div>

  34.  </div>

  35.  <script src="js/MD5.js"></script>

  36.  <script src="js/script.js"></script>

  37. </body>

  38. </html>

css代碼:


 
  1. *{

  2.  margin: 0;

  3.  padding: 0;

  4.  font-family: "微軟雅黑";

  5. }

  6. html,body {

  7.  height: 100%;

  8. }

  9. li {

  10.  list-style: none;

  11. }

  12. body {

  13.  overflow: hidden;

  14. }

  15. #main {

  16.  width: 1000px;

  17.  height: 80%;

  18.  margin: 5% auto;

  19. }

  20. #main .left {

  21.  float: left;

  22.  width: 350px;

  23.  height:330px;

  24.  margin: 50px 0 0 50px;

  25.  background-color: #fff;

  26.  border: 1px solid #000;

  27.  box-sizing: border-box;

  28.  color: #fff;

  29.  border-top-left-radius: 15px;

  30.  border-top-right-radius: 15px;

  31. }

  32. #main .right {

  33.  float: right;

  34.  width: 350px;

  35.  height: 330px;

  36.  margin: 50px 50px 0 0;

  37.  background-color: #fff;

  38.  box-sizing: border-box;

  39.  border: 1px solid #000;

  40.  border-top-left-radius: 15px;

  41.  border-top-right-radius: 15px;

  42. }

  43. #main .title {

  44.  width: 100%;

  45.  height: 40px;

  46.  background-color: #333;

  47.  line-height: 40px;

  48.  text-indent: 20px;

  49.  position: relative;

  50.  color: #fff;

  51.  border-top-left-radius: 15px;

  52.  border-top-right-radius: 15px;

  53. }

  54. #main .lang {

  55.  height: 40px;

  56.  line-height: 40px;

  57.  text-indent: 20px;

  58.  letter-spacing: 2px;

  59.  text-decoration: underline;

  60.  color: #58a;

  61.  cursor: pointer;

  62. }

  63. #main .lang:hover {

  64.  text-decoration: none;

  65.  color: #eee;

  66. }

  67. #main .text {

  68.  width: 100%;

  69.  height: 288px;

  70.  padding: 20px;

  71.  box-sizing: border-box;

  72.  resize: none;

  73.  outline: none;

  74.  border: none;

  75. }

  76. #main .right .cont {

  77.  width: 100%;

  78.  height: 295px;

  79.  padding: 20px;

  80.  box-sizing: border-box;

  81. }

  82. #main .bottom {

  83.  float: left;

  84.  width: 100%;

  85.  height: 40px;

  86.  margin-top: 60px;

  87. }

  88. #main .bottom button {

  89.  float: right;

  90.  width: 65px;

  91.  height: 35px;

  92.  line-height: 35px;

  93.  letter-spacing: 2px;

  94.  border: none;

  95.  margin-right: 50px;

  96.  border-radius: 3px;

  97.  outline: none;

  98.  cursor: pointer;

  99.  color: #eee;

  100.  background-color: #333;

  101. }

  102. #main ul {

  103.  width: 100%;

  104.  padding: 20px 15px 0 20px;

  105.  box-sizing: border-box;

  106.  position: absolute;

  107.  background: blue;

  108.  background-color: #fff;

  109.  border-bottom: 1px solid #333;

  110.  display: none;

  111. }

  112. #main ul li {

  113.  float:left;

  114.  text-indent: 0;

  115.  text-align: center;

  116.  padding: 0 10px;

  117.  margin: 0 10px;

  118.  margin-bottom: 20px;

  119.  border: 1px solid #000;

  120.  border-radius: 5px;

  121.  box-sizing: border-box;

  122.  color: #333;

  123.  cursor: pointer;

  124. }

  125. #main ul li:hover {

  126.  background-color: #333;

  127.  color: #fff;

  128. }

2,瞭解百度翻譯API

這隻只對所配置的參數做一介紹,官方API也有做解釋:

進入百度翻譯,左下角如圖:

點擊百度翻譯開放平臺:

 

  • q是你要翻譯的字符串

  • from是你在輸入時的語言

  • to是你要翻譯成什麼語言

  • appid是你申請的百度翻譯測試賬號(註冊後秒發)

  • salt是一個隨機數,這裏用事件表示

  • sign是對拼接的字符串的MD5加密,至於拼接的字符串其實就是: 待加密字符串 =
    appid+q+salt+祕鑰(申請賬號時密碼也會給你) 最後把 待價密 的字符串傳入MD5函數,返回sign.

完整流程如圖:

3.準備MD5加密函數(可以百度自己搜,這裏直接附代碼)

MD5加密字符串:


 
  1. var MD5 = function (string) {

  2.  

  3.    function RotateLeft(lValue, iShiftBits) {

  4.        return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));

  5.    }

  6.  

  7.    function AddUnsigned(lX,lY) {

  8.        var lX4,lY4,lX8,lY8,lResult;

  9.        lX8 = (lX & 0x80000000);

  10.        lY8 = (lY & 0x80000000);

  11.        lX4 = (lX & 0x40000000);

  12.        lY4 = (lY & 0x40000000);

  13.        lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);

  14.        if (lX4 & lY4) {

  15.            return (lResult ^ 0x80000000 ^ lX8 ^ lY8);

  16.        }

  17.        if (lX4 | lY4) {

  18.            if (lResult & 0x40000000) {

  19.                return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);

  20.            } else {

  21.                return (lResult ^ 0x40000000 ^ lX8 ^ lY8);

  22.            }

  23.        } else {

  24.            return (lResult ^ lX8 ^ lY8);

  25.        }

  26.    }

  27.  

  28.    function F(x,y,z) { return (x & y) | ((~x) & z); }

  29.    function G(x,y,z) { return (x & z) | (y & (~z)); }

  30.    function H(x,y,z) { return (x ^ y ^ z); }

  31.    function I(x,y,z) { return (y ^ (x | (~z))); }

  32.  

  33.    function FF(a,b,c,d,x,s,ac) {

  34.        a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));

  35.        return AddUnsigned(RotateLeft(a, s), b);

  36.    };

  37.  

  38.    function GG(a,b,c,d,x,s,ac) {

  39.        a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));

  40.        return AddUnsigned(RotateLeft(a, s), b);

  41.    };

  42.  

  43.    function HH(a,b,c,d,x,s,ac) {

  44.        a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));

  45.        return AddUnsigned(RotateLeft(a, s), b);

  46.    };

  47.  

  48.    function II(a,b,c,d,x,s,ac) {

  49.        a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));

  50.        return AddUnsigned(RotateLeft(a, s), b);

  51.    };

  52.  

  53.    function ConvertToWordArray(string) {

  54.        var lWordCount;

  55.        var lMessageLength = string.length;

  56.        var lNumberOfWords_temp1=lMessageLength + 8;

  57.        var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;

  58.        var lNumberOfWords = (lNumberOfWords_temp2+1)*16;

  59.        var lWordArray=Array(lNumberOfWords-1);

  60.        var lBytePosition = 0;

  61.        var lByteCount = 0;

  62.        while ( lByteCount < lMessageLength ) {

  63.            lWordCount = (lByteCount-(lByteCount % 4))/4;

  64.            lBytePosition = (lByteCount % 4)*8;

  65.            lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));

  66.            lByteCount++;

  67.        }

  68.        lWordCount = (lByteCount-(lByteCount % 4))/4;

  69.        lBytePosition = (lByteCount % 4)*8;

  70.        lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);

  71.        lWordArray[lNumberOfWords-2] = lMessageLength<<3;

  72.        lWordArray[lNumberOfWords-1] = lMessageLength>>>29;

  73.        return lWordArray;

  74.    };

  75.  

  76.    function WordToHex(lValue) {

  77.        var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;

  78.        for (lCount = 0;lCount<=3;lCount++) {

  79.            lByte = (lValue>>>(lCount*8)) & 255;

  80.            WordToHexValue_temp = "0" + lByte.toString(16);

  81.            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);

  82.        }

  83.        return WordToHexValue;

  84.    };

  85.  

  86.    function Utf8Encode(string) {

  87.        string = string.replace(/\r\n/g,"\n");

  88.        var utftext = "";

  89.  

  90.        for (var n = 0; n < string.length; n++) {

  91.  

  92.            var c = string.charCodeAt(n);

  93.  

  94.            if (c < 128) {

  95.                utftext += String.fromCharCode(c);

  96.            }

  97.            else if((c > 127) && (c < 2048)) {

  98.                utftext += String.fromCharCode((c >> 6) | 192);

  99.                utftext += String.fromCharCode((c & 63) | 128);

  100.            }

  101.            else {

  102.                utftext += String.fromCharCode((c >> 12) | 224);

  103.                utftext += String.fromCharCode(((c >> 6) & 63) | 128);

  104.                utftext += String.fromCharCode((c & 63) | 128);

  105.            }

  106.  

  107.        }

  108.  

  109.        return utftext;

  110.    };

  111.  

  112.    var x=Array();

  113.    var k,AA,BB,CC,DD,a,b,c,d;

  114.    var S11=7, S12=12, S13=17, S14=22;

  115.    var S21=5, S22=9 , S23=14, S24=20;

  116.    var S31=4, S32=11, S33=16, S34=23;

  117.    var S41=6, S42=10, S43=15, S44=21;

  118.  

  119.    string = Utf8Encode(string);

  120.  

  121.    x = ConvertToWordArray(string);

  122.  

  123.    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;

  124.  

  125.    for (k=0;k<x.length;k+=16) {

  126.        AA=a; BB=b; CC=c; DD=d;

  127.        a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);

  128.        d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);

  129.        c=FF(c,d,a,b,x[k+2], S13,0x242070DB);

  130.        b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);

  131.        a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);

  132.        d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);

  133.        c=FF(c,d,a,b,x[k+6], S13,0xA8304613);

  134.        b=FF(b,c,d,a,x[k+7], S14,0xFD469501);

  135.        a=FF(a,b,c,d,x[k+8], S11,0x698098D8);

  136.        d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);

  137.        c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);

  138.        b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);

  139.        a=FF(a,b,c,d,x[k+12],S11,0x6B901122);

  140.        d=FF(d,a,b,c,x[k+13],S12,0xFD987193);

  141.        c=FF(c,d,a,b,x[k+14],S13,0xA679438E);

  142.        b=FF(b,c,d,a,x[k+15],S14,0x49B40821);

  143.        a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);

  144.        d=GG(d,a,b,c,x[k+6], S22,0xC040B340);

  145.        c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);

  146.        b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);

  147.        a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);

  148.        d=GG(d,a,b,c,x[k+10],S22,0x2441453);

  149.        c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);

  150.        b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);

  151.        a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);

  152.        d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);

  153.        c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);

  154.        b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);

  155.        a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);

  156.        d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);

  157.        c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);

  158.        b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);

  159.        a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);

  160.        d=HH(d,a,b,c,x[k+8], S32,0x8771F681);

  161.        c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);

  162.        b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);

  163.        a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);

  164.        d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);

  165.        c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);

  166.        b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);

  167.        a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);

  168.        d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);

  169.        c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);

  170.        b=HH(b,c,d,a,x[k+6], S34,0x4881D05);

  171.        a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);

  172.        d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);

  173.        c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);

  174.        b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);

  175.        a=II(a,b,c,d,x[k+0], S41,0xF4292244);

  176.        d=II(d,a,b,c,x[k+7], S42,0x432AFF97);

  177.        c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);

  178.        b=II(b,c,d,a,x[k+5], S44,0xFC93A039);

  179.        a=II(a,b,c,d,x[k+12],S41,0x655B59C3);

  180.        d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);

  181.        c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);

  182.        b=II(b,c,d,a,x[k+1], S44,0x85845DD1);

  183.        a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);

  184.        d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);

  185.        c=II(c,d,a,b,x[k+6], S43,0xA3014314);

  186.        b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);

  187.        a=II(a,b,c,d,x[k+4], S41,0xF7537E82);

  188.        d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);

  189.        c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);

  190.        b=II(b,c,d,a,x[k+9], S44,0xEB86D391);

  191.        a=AddUnsigned(a,AA);

  192.        b=AddUnsigned(b,BB);

  193.        c=AddUnsigned(c,CC);

  194.        d=AddUnsigned(d,DD);

  195.    }

  196.  

  197.    var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);

  198.  

  199.    return temp.toLowerCase();

  200. }

加密:

發送請求時別忘了在參數最後面加上一個callback參數用來接收返回值

callback函數:


 
  1. function fn(str) {

  2.  var result = document.querySelector(".right .cont");

  3.  result.innerHTML = str.trans_result[0].dst;

  4. }

4.寫js

這裏簡單的邏輯就不說了,說說這裏的接口請求的實現和實現實時翻譯的邏輯(每輸入一兩個字就會主動給你翻譯)。首先這個列子的核心就是jsonp的跨域請求原理很簡單,就是每次請求都給他創建一個 <script>標籤插入 body, 每次給標籤的 src傳入不同的參數,待服務器給你返回數據,最終拿到數據渲染到頁面。這裏要提醒的是要給請求的參數最後面加上一個回調函數,返回過來的數據客戶端可以從回調函數中拿取。其次就是實時翻譯,原理就是在敲鍵盤時每次按鍵擡起時隔一定的時間去請求,那就是鍵盤事件加上 setInterval();每隔500ms去請求。

整個過程的代碼如下:


 
  1. (function() {

  2.  var title = document.querySelector(".left .title .lang"),

  3.      ul = document.querySelector(".ul1"),

  4.      lis = document.querySelectorAll(".ul1 li"),

  5.      text = document.querySelector(".left .text"),

  6.      result = document.querySelector(".right .cont"),

  7.      reset = document.querySelector(".bottom .reset"),

  8.      trans = document.querySelector(".bottom .trans"),

  9.      key = true,

  10.      length = lis.length,

  11.      lang = "en",

  12.      timer = null;

  13.  

  14.  function langShow() {

  15.    if (key == true) {

  16.      ul.style.display = "block";

  17.      key = false;

  18.    } else {

  19.      ul.style.display = "none";

  20.      key = true;

  21.    }

  22.  }

  23.  

  24.  function changeLang() {

  25.    lang = this.getAttribute('data-lang');

  26.    title.innerHTML = this.innerHTML;

  27.    this.parentNode.style.display = "none";

  28.    key = true;

  29.  }

  30.  

  31.  function createScript(src) {

  32.    var script = document.createElement('script');

  33.    script.id = "script1"

  34.    script.src = src;

  35.    document.body.appendChild(script);

  36.  }

  37.  

  38.  function translate() {

  39.    var value = 'http://api.fanyi.baidu.com/api/trans/vip/translate?';

  40.    var date = Date.now();

  41.    var str = '20170605000052254'+text.value+date+'63r1c42X7_buc4OrXm1g';

  42.    var md5 = MD5(str);

  43.    var data = 'q=' + text.value + '&from=auto&to=' + lang + '&appid=20170605000052254' + '&salt=' + date + '&sign=' + md5 + "&callback=fn";

  44.    var src = value + data;

  45.    createScript(src);

  46.  }

  47.  

  48.  function init() {

  49.  

  50.    title.onclick = langShow;

  51.  

  52.    for (var i = 0; i < length; i++) {

  53.      lis[i].onclick = changeLang;

  54.    }

  55.  

  56.    reset.onclick = function() {

  57.      text.value = "";

  58.    }

  59.  

  60.    trans.onclick = function() {

  61.      if (text.value == "") {

  62.        return;

  63.      }

  64.      var script = document.querySelector('#script1');

  65.      if (script) {

  66.        script.parentNode.removeChild(script);

  67.        translate();

  68.      } else {

  69.        translate();

  70.      }

  71.    }

  72.  

  73.    text.onkeydown = function() {

  74.      clearTimeout(timer);

  75.      timer = setInterval(function() {

  76.        if (text.value == "") {

  77.          return;

  78.        }

  79.        var script = document.querySelector('#script1');

  80.        if (script) {

  81.          script.parentNode.removeChild(script);

  82.          translate();

  83.        } else {

  84.          translate();

  85.        }

  86.      }, 500);

  87.      clearTimeout(timer);

  88.    }

  89.  }

  90.  init();

  91. })();

  92. function fn(str) {

  93.  var result = document.querySelector(".right .cont");

  94.  result.innerHTML = str.trans_result[0].dst;

  95. }

以上就是實現翻譯的過程,效果圖:

中 - 英

中 - 韓

這樣一個小小的翻譯小Demo就完成了,主要還是練習原生js,理解跨域請求的原理,其實跨域請求的方法很多,比如 <img>標籤的 src <iframe>等等。這些方法大家都得去一一瞭解。

 

時間太久,忘了從哪裏轉的了,如有冒犯或原作者看到,請私信我添加原文鏈接或刪除,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章