1. 背景:
平時不知道用js寫什麼練手,這裏就寫了一個類似百度翻譯的小demo。大家可以平時沒事兒了看看書,寫寫像這種類型的小demo,調用以下公開的api即可。對於學生黨,能進入學校實驗室做項目更好。進不去的,平時寫寫小demo練練也不差。(我爲什麼沒在實驗室)
2. demo前準備工作:
-
頁面佈局
-
瞭解百度翻譯API,所需配置參數
-
準備 MD5.js 加密算法函數(百度自己搜)
-
寫js代碼
3. 步驟:
1. 頁面佈局:佈局就不說了,直接貼圖上代碼:
可進行語言切換
html代碼:
-
<!DOCTYPE html>
-
<html>
-
<head>
-
<meta charset="utf-8">
-
<title></title>
-
<link rel="stylesheet" type="text/css" href="css/style.css">
-
</head>
-
<body>
-
<div id="main">
-
<div class="left">
-
<div class="title">
-
要翻譯爲:
-
<span class="lang">英文</span>
-
<ul class="ul1">
-
<li data-lang="en">英語</li>
-
<li data-lang="zh">中文</li>
-
<li data-lang="jp">日語</li>
-
<li data-lang="kor">韓語</li>
-
<li data-lang="fra">法語</li>
-
<li data-lang="ru">俄語</li>
-
<li data-lang="de">德語</li>
-
</ul>
-
</div>
-
<textarea class="text" placeholder="要翻譯的單詞/句子" value=""></textarea>
-
</div>
-
<div class="right">
-
<div class="title">翻譯結果:</div>
-
<div class="cont"></div>
-
</div>
-
<div class="bottom">
-
<button class="reset">清除</button>
-
<button class="trans">翻譯</button>
-
</div>
-
</div>
-
<script src="js/MD5.js"></script>
-
<script src="js/script.js"></script>
-
</body>
-
</html>
css代碼:
-
*{
-
margin: 0;
-
padding: 0;
-
font-family: "微軟雅黑";
-
}
-
html,body {
-
height: 100%;
-
}
-
li {
-
list-style: none;
-
}
-
body {
-
overflow: hidden;
-
}
-
#main {
-
width: 1000px;
-
height: 80%;
-
margin: 5% auto;
-
}
-
#main .left {
-
float: left;
-
width: 350px;
-
height:330px;
-
margin: 50px 0 0 50px;
-
background-color: #fff;
-
border: 1px solid #000;
-
box-sizing: border-box;
-
color: #fff;
-
border-top-left-radius: 15px;
-
border-top-right-radius: 15px;
-
}
-
#main .right {
-
float: right;
-
width: 350px;
-
height: 330px;
-
margin: 50px 50px 0 0;
-
background-color: #fff;
-
box-sizing: border-box;
-
border: 1px solid #000;
-
border-top-left-radius: 15px;
-
border-top-right-radius: 15px;
-
}
-
#main .title {
-
width: 100%;
-
height: 40px;
-
background-color: #333;
-
line-height: 40px;
-
text-indent: 20px;
-
position: relative;
-
color: #fff;
-
border-top-left-radius: 15px;
-
border-top-right-radius: 15px;
-
}
-
#main .lang {
-
height: 40px;
-
line-height: 40px;
-
text-indent: 20px;
-
letter-spacing: 2px;
-
text-decoration: underline;
-
color: #58a;
-
cursor: pointer;
-
}
-
#main .lang:hover {
-
text-decoration: none;
-
color: #eee;
-
}
-
#main .text {
-
width: 100%;
-
height: 288px;
-
padding: 20px;
-
box-sizing: border-box;
-
resize: none;
-
outline: none;
-
border: none;
-
}
-
#main .right .cont {
-
width: 100%;
-
height: 295px;
-
padding: 20px;
-
box-sizing: border-box;
-
}
-
#main .bottom {
-
float: left;
-
width: 100%;
-
height: 40px;
-
margin-top: 60px;
-
}
-
#main .bottom button {
-
float: right;
-
width: 65px;
-
height: 35px;
-
line-height: 35px;
-
letter-spacing: 2px;
-
border: none;
-
margin-right: 50px;
-
border-radius: 3px;
-
outline: none;
-
cursor: pointer;
-
color: #eee;
-
background-color: #333;
-
}
-
#main ul {
-
width: 100%;
-
padding: 20px 15px 0 20px;
-
box-sizing: border-box;
-
position: absolute;
-
background: blue;
-
background-color: #fff;
-
border-bottom: 1px solid #333;
-
display: none;
-
}
-
#main ul li {
-
float:left;
-
text-indent: 0;
-
text-align: center;
-
padding: 0 10px;
-
margin: 0 10px;
-
margin-bottom: 20px;
-
border: 1px solid #000;
-
border-radius: 5px;
-
box-sizing: border-box;
-
color: #333;
-
cursor: pointer;
-
}
-
#main ul li:hover {
-
background-color: #333;
-
color: #fff;
-
}
2,瞭解百度翻譯API
這隻只對所配置的參數做一介紹,官方API也有做解釋:
進入百度翻譯,左下角如圖:
點擊百度翻譯開放平臺:
-
q是你要翻譯的字符串
-
from是你在輸入時的語言
-
to是你要翻譯成什麼語言
-
appid是你申請的百度翻譯測試賬號(註冊後秒發)
-
salt是一個隨機數,這裏用事件表示
-
sign是對拼接的字符串的MD5加密,至於拼接的字符串其實就是: 待加密字符串 =
appid+q+salt+祕鑰(申請賬號時密碼也會給你) 最後把 待價密 的字符串傳入MD5函數,返回sign.
完整流程如圖:
3.準備MD5加密函數(可以百度自己搜,這裏直接附代碼)
MD5加密字符串:
-
var MD5 = function (string) {
-
-
function RotateLeft(lValue, iShiftBits) {
-
return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
-
}
-
-
function AddUnsigned(lX,lY) {
-
var lX4,lY4,lX8,lY8,lResult;
-
lX8 = (lX & 0x80000000);
-
lY8 = (lY & 0x80000000);
-
lX4 = (lX & 0x40000000);
-
lY4 = (lY & 0x40000000);
-
lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
-
if (lX4 & lY4) {
-
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
-
}
-
if (lX4 | lY4) {
-
if (lResult & 0x40000000) {
-
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
-
} else {
-
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
-
}
-
} else {
-
return (lResult ^ lX8 ^ lY8);
-
}
-
}
-
-
function F(x,y,z) { return (x & y) | ((~x) & z); }
-
function G(x,y,z) { return (x & z) | (y & (~z)); }
-
function H(x,y,z) { return (x ^ y ^ z); }
-
function I(x,y,z) { return (y ^ (x | (~z))); }
-
-
function FF(a,b,c,d,x,s,ac) {
-
a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
-
return AddUnsigned(RotateLeft(a, s), b);
-
};
-
-
function GG(a,b,c,d,x,s,ac) {
-
a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
-
return AddUnsigned(RotateLeft(a, s), b);
-
};
-
-
function HH(a,b,c,d,x,s,ac) {
-
a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
-
return AddUnsigned(RotateLeft(a, s), b);
-
};
-
-
function II(a,b,c,d,x,s,ac) {
-
a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
-
return AddUnsigned(RotateLeft(a, s), b);
-
};
-
-
function ConvertToWordArray(string) {
-
var lWordCount;
-
var lMessageLength = string.length;
-
var lNumberOfWords_temp1=lMessageLength + 8;
-
var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
-
var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
-
var lWordArray=Array(lNumberOfWords-1);
-
var lBytePosition = 0;
-
var lByteCount = 0;
-
while ( lByteCount < lMessageLength ) {
-
lWordCount = (lByteCount-(lByteCount % 4))/4;
-
lBytePosition = (lByteCount % 4)*8;
-
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
-
lByteCount++;
-
}
-
lWordCount = (lByteCount-(lByteCount % 4))/4;
-
lBytePosition = (lByteCount % 4)*8;
-
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
-
lWordArray[lNumberOfWords-2] = lMessageLength<<3;
-
lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
-
return lWordArray;
-
};
-
-
function WordToHex(lValue) {
-
var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
-
for (lCount = 0;lCount<=3;lCount++) {
-
lByte = (lValue>>>(lCount*8)) & 255;
-
WordToHexValue_temp = "0" + lByte.toString(16);
-
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
-
}
-
return WordToHexValue;
-
};
-
-
function Utf8Encode(string) {
-
string = string.replace(/\r\n/g,"\n");
-
var utftext = "";
-
-
for (var n = 0; n < string.length; n++) {
-
-
var c = string.charCodeAt(n);
-
-
if (c < 128) {
-
utftext += String.fromCharCode(c);
-
}
-
else if((c > 127) && (c < 2048)) {
-
utftext += String.fromCharCode((c >> 6) | 192);
-
utftext += String.fromCharCode((c & 63) | 128);
-
}
-
else {
-
utftext += String.fromCharCode((c >> 12) | 224);
-
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
-
utftext += String.fromCharCode((c & 63) | 128);
-
}
-
-
}
-
-
return utftext;
-
};
-
-
var x=Array();
-
var k,AA,BB,CC,DD,a,b,c,d;
-
var S11=7, S12=12, S13=17, S14=22;
-
var S21=5, S22=9 , S23=14, S24=20;
-
var S31=4, S32=11, S33=16, S34=23;
-
var S41=6, S42=10, S43=15, S44=21;
-
-
string = Utf8Encode(string);
-
-
x = ConvertToWordArray(string);
-
-
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
-
-
for (k=0;k<x.length;k+=16) {
-
AA=a; BB=b; CC=c; DD=d;
-
a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
-
d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
-
c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
-
b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
-
a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
-
d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
-
c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
-
b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
-
a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
-
d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
-
c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
-
b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
-
a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
-
d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
-
c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
-
b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
-
a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
-
d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
-
c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
-
b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
-
a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
-
d=GG(d,a,b,c,x[k+10],S22,0x2441453);
-
c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
-
b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
-
a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
-
d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
-
c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
-
b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
-
a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
-
d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
-
c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
-
b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
-
a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
-
d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
-
c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
-
b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
-
a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
-
d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
-
c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
-
b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
-
a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
-
d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
-
c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
-
b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
-
a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
-
d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
-
c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
-
b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
-
a=II(a,b,c,d,x[k+0], S41,0xF4292244);
-
d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
-
c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
-
b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
-
a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
-
d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
-
c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
-
b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
-
a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
-
d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
-
c=II(c,d,a,b,x[k+6], S43,0xA3014314);
-
b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
-
a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
-
d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
-
c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
-
b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
-
a=AddUnsigned(a,AA);
-
b=AddUnsigned(b,BB);
-
c=AddUnsigned(c,CC);
-
d=AddUnsigned(d,DD);
-
}
-
-
var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
-
-
return temp.toLowerCase();
-
}
加密:
發送請求時別忘了在參數最後面加上一個callback參數用來接收返回值
callback函數:
-
function fn(str) {
-
var result = document.querySelector(".right .cont");
-
result.innerHTML = str.trans_result[0].dst;
-
}
4.寫js
這裏簡單的邏輯就不說了,說說這裏的接口請求的實現和實現實時翻譯的邏輯(每輸入一兩個字就會主動給你翻譯)。首先這個列子的核心就是jsonp的跨域請求原理很簡單,就是每次請求都給他創建一個 <script>
標籤插入 body
, 每次給標籤的 src
傳入不同的參數,待服務器給你返回數據,最終拿到數據渲染到頁面。這裏要提醒的是要給請求的參數最後面加上一個回調函數,返回過來的數據客戶端可以從回調函數中拿取。其次就是實時翻譯,原理就是在敲鍵盤時每次按鍵擡起時隔一定的時間去請求,那就是鍵盤事件加上 setInterval()
;每隔500ms去請求。
整個過程的代碼如下:
-
(function() {
-
var title = document.querySelector(".left .title .lang"),
-
ul = document.querySelector(".ul1"),
-
lis = document.querySelectorAll(".ul1 li"),
-
text = document.querySelector(".left .text"),
-
result = document.querySelector(".right .cont"),
-
reset = document.querySelector(".bottom .reset"),
-
trans = document.querySelector(".bottom .trans"),
-
key = true,
-
length = lis.length,
-
lang = "en",
-
timer = null;
-
-
function langShow() {
-
if (key == true) {
-
ul.style.display = "block";
-
key = false;
-
} else {
-
ul.style.display = "none";
-
key = true;
-
}
-
}
-
-
function changeLang() {
-
lang = this.getAttribute('data-lang');
-
title.innerHTML = this.innerHTML;
-
this.parentNode.style.display = "none";
-
key = true;
-
}
-
-
function createScript(src) {
-
var script = document.createElement('script');
-
script.id = "script1"
-
script.src = src;
-
document.body.appendChild(script);
-
}
-
-
function translate() {
-
var value = 'http://api.fanyi.baidu.com/api/trans/vip/translate?';
-
var date = Date.now();
-
var str = '20170605000052254'+text.value+date+'63r1c42X7_buc4OrXm1g';
-
var md5 = MD5(str);
-
var data = 'q=' + text.value + '&from=auto&to=' + lang + '&appid=20170605000052254' + '&salt=' + date + '&sign=' + md5 + "&callback=fn";
-
var src = value + data;
-
createScript(src);
-
}
-
-
function init() {
-
-
title.onclick = langShow;
-
-
for (var i = 0; i < length; i++) {
-
lis[i].onclick = changeLang;
-
}
-
-
reset.onclick = function() {
-
text.value = "";
-
}
-
-
trans.onclick = function() {
-
if (text.value == "") {
-
return;
-
}
-
var script = document.querySelector('#script1');
-
if (script) {
-
script.parentNode.removeChild(script);
-
translate();
-
} else {
-
translate();
-
}
-
}
-
-
text.onkeydown = function() {
-
clearTimeout(timer);
-
timer = setInterval(function() {
-
if (text.value == "") {
-
return;
-
}
-
var script = document.querySelector('#script1');
-
if (script) {
-
script.parentNode.removeChild(script);
-
translate();
-
} else {
-
translate();
-
}
-
}, 500);
-
clearTimeout(timer);
-
}
-
}
-
init();
-
})();
-
function fn(str) {
-
var result = document.querySelector(".right .cont");
-
result.innerHTML = str.trans_result[0].dst;
-
}
以上就是實現翻譯的過程,效果圖:
中 - 英
中 - 韓
這樣一個小小的翻譯小Demo就完成了,主要還是練習原生js,理解跨域請求的原理,其實跨域請求的方法很多,比如 <img>
標籤的 src
, <iframe>
等等。這些方法大家都得去一一瞭解。
時間太久,忘了從哪裏轉的了,如有冒犯或原作者看到,請私信我添加原文鏈接或刪除,謝謝!