移動端webapp點(diǎn)詞翻譯的設(shè)計(jì)與實(shí)現(xiàn)

單詞翻譯常見于APP中秆剪,那么在網(wǎng)頁中對于一段中英混雜的內(nèi)容怎么準(zhǔn)確的做到單詞的翻譯呢赊淑?

我要渲染的內(nèi)容是一段段的html,用react渲染一段html內(nèi)容是沒有什么難度仅讽,使用dangerouslySetInnerHTML 即可陶缺。但是可以做到將內(nèi)容中的英文單詞翻譯出來,是怎么實(shí)現(xiàn)的呢何什?一起來看一下吧组哩。

效果

image

事情是這樣的...

我前端是做內(nèi)容展示,后臺將Html格式的內(nèi)容傳遞到前端处渣,前端原生元素的dangerouslySetInnerHTML 屬性去解析html內(nèi)容,就可以使用react框架渲染html了

image

仔細(xì)看蛛砰,這個(gè)屬性用的是{{ }}2個(gè)括號而不是1個(gè)括號罐栈。原因是:第一{}代表jsx語法開始,第二個(gè)是代表dangerouslySetInnerHTML接收的是一個(gè)對象鍵值對泥畅。它接收的內(nèi)容是html的荠诬,很容易收到XSS攻擊,所以這個(gè)屬性有了dangerous這個(gè)單詞...

過程

  • 重組英文單詞
    后臺傳給我的一段一段的內(nèi)容是這樣的:
image

既然要提取出來做單詞翻譯位仁,就得有能力去獲取每一個(gè)單詞柑贞,所以我的打算是,把內(nèi)容提取出來聂抢,是一個(gè)英文單詞就放進(jìn)一個(gè)span標(biāo)簽中钧嘶。但是這一步在哪里處理比較好呢,我想了想琳疏,在頁面渲染之前處理吧有决, 這樣頁面渲染的壓力要減小闸拿,提高渲染速度。所以我在前端接收到后端發(fā)送的數(shù)據(jù)之后书幕,在存入store之前就先處理好新荤。

        case "OBT_BOOK_CONTENT_SUCCESS":
            var newContents = action.meta.bookcontent.map((item, index) => {
                item.paragraphContent = item.paragraphContent.replace(/src="/g, `src="${url}`);
                //處理caseContent中的單詞
                var div = document.createElement('div');
                div.innerHTML = item.paragraphContent;
                var caseContent = div.querySelector('.caseContent');

                if (caseContent) {
                    var arr = caseContent.innerText.split(" ");
                    for (var i = 0; i < arr.length; i++) {
                        arr[i] = "<span>" + arr[i] + "</span>"
                    }
                    caseContent.innerHTML = arr.join("");
                    item.paragraphContent = div.innerHTML;
                }
                return item;
            })
            return Object.assign({}, state, {
                bookcontent: newContents
            })

由于傳給我的是一大段內(nèi)容,里面的元素的類型不只一種台汇、類名也不止一種苛骨,有div .caseTitle .caseContent strong等等,但是我只處理面積最大的一塊英文苟呐,也就是只處理caseContent中的英文單詞這就好辦了痒芝。我沒有用string的方法,去查找這個(gè)串在什么位置掠抬,怎么截取怎么拼接吼野。沒有。我利用了DOM的原理两波,借助DOM原生的api幫助我得到我要的英文單詞瞳步。我創(chuàng)建了一個(gè)div(沒有DOM我就自己創(chuàng)建DOM咯),然后DOM查找.caseContent腰奋,用空格把其中的所有單詞提取出來单起,再給每一個(gè)單詞用span包起來,然后把.caseContent中的內(nèi)容替換掉,同時(shí)div的innerHTML也就變了劣坊,最后改變paragraphContent嘀倒。就這樣把后端傳過來的東西做了修改,再使用局冰。

  • 提取單詞
    由于我想要翻譯的單詞是用span包裹的测蘑,所以我需要檢查用戶點(diǎn)擊屏幕所在的節(jié)點(diǎn)是不是span
if(e.target.nodeName === 'SPAN'){
        var s = "";
       if(e.target.innerText) {
            var len = e.target.innerText.length;
            if( !/^[\u4e00-\u9fa5]{0,}$/.test(e.target.innerText) ){
                if(e.target.innerText[len -1 ] === ',' || e.target.innerText[len -1 ] === '.' ){
                    s = e.target.innerText.substring(0, len -1 )
                }else {
                    s = e.target.innerText;
                }
                var chooseSpan =   e.target;
               
                this.props.checkWords(s, chooseSpan);
            }
       }
       console.log( s);
    }

利用正則!/^[\u4e00-\u9fa5]{0,}$/提取出來英文單詞,但是有些單詞末尾會帶著英文狀態(tài)下的逗號,句號.康二,所以還需要用substring剪切一下單詞碳胳,再調(diào)用方法。

這里沫勿,提取頁面中點(diǎn)擊的內(nèi)容挨约,需要CSS的配合。

user-select: text;

user-selct: text;可以讓頁面中的內(nèi)容被選中产雹。而 user-select: none是讓頁面中的內(nèi)容不被選中诫惭。

  -ms-user-select: none;
  -webkit-user-select: none;
  user-select: none;

獲取了單詞s之后,還需要做一點(diǎn)交互蔓挖,就是被選中的單詞高亮起來夕土,所有,span元素也需要被處理时甚,為了嚴(yán)謹(jǐn)隘弊,所以需要再判斷是不是單詞哈踱,是的話,再對span 做處理梨熙。

 checkWords(txt, selectedSpan) {
    // 查單詞
   
    this.selectedSpan = selectedSpan;
    if (txt.toString().length > 1) {
      if (/^\w+$/.test(txt)) {
        this.props.getWord(txt);
        this.setState({
          showWord: true
        })
        selectedSpan.style.color="#fff";
        selectedSpan.style.backgroundColor="rgb(0,153,223)";
      }
    }
  }
  • 請求翻譯接口
    getWord方法中調(diào)用了查單詞的api,我用的是有道智云的api开镣,需要自己注冊一個(gè)賬號,然后申請一個(gè)應(yīng)用咽扇。獲取appKey和appSecret,設(shè)置好from 和 to 的值邪财,也就是你要從什么語言轉(zhuǎn)什么語言,準(zhǔn)備一個(gè)隨機(jī)數(shù)salt质欲, 然后各種生成簽名一波操作树埠。
var appSecret = 'GOPjZoiSnH592P31Qn6xoallHn3zUnSh';
  var appKey = '06fc15a9c06cb290';
  var salt = '' + (new Date).getTime();
  // 多個(gè)query可以用\n連接  如 query='apple\norange\nbanana\npear'
  var from = 'en';
  var to = 'zh-CHS';
  var str1 = appKey + q + salt + appSecret;
  var data = null;
  var sign = md5(str1);
  var sendRes = res;
  sign = sign.toUpperCase();
  q = encodeURI(q);
  var url = `http://openapi.youdao.com/api?q=${q}&from=${from}&to=${to}&appKey=${appKey}&salt=${salt}&sign=${sign}`

有了這個(gè)url之后,就可以請求了嘶伟。返回的東西是:

image

播放單詞的地方就是用 H5的audio 元素,src是
http://dict.youdao.com/dictvoice?audio=${this.props.word.query}

<audio   id="audio" >
      <source src={voiceUrl} type="audio/mp3"></source>
 </audio>

后來發(fā)現(xiàn)扇貝的單詞api做的也不錯(cuò)怎憋,沒有有道用的這么麻煩,有道還需要簽名九昧,用戶量大的時(shí)候也會有限制绊袋,準(zhǔn)備以后換扇貝的。

完畢

至此铸鹰,使用react框架完成移動頁面的定向單詞翻譯已完成癌别。其中配合了CSS,DOM,正則蹋笼,使用別家api等知識展姐,算是一次小小的綜合考核吧,不知道有沒有其他同學(xué)也做過這樣的事情剖毯,如果有的話圾笨,可以交流一下啊。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末逊谋,一起剝皮案震驚了整個(gè)濱河市墅拭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌涣狗,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舒憾,死亡現(xiàn)場離奇詭異镀钓,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)镀迂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進(jìn)店門丁溅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人探遵,你說我怎么就攤上這事窟赏〖斯瘢” “怎么了?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵涯穷,是天一觀的道長棍掐。 經(jīng)常有香客問我,道長拷况,這世上最難降的妖魔是什么作煌? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮赚瘦,結(jié)果婚禮上粟誓,老公的妹妹穿的比我還像新娘。我一直安慰自己起意,他們只是感情好鹰服,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布黍图。 她就那樣靜靜地躺著藤树,像睡著了一般沐祷。 火紅的嫁衣襯著肌膚如雪喜爷。 梳的紋絲不亂的頭發(fā)上琳水,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天蜈七,我揣著相機(jī)與錄音脸候,去河邊找鬼获列。 笑死逗爹,一個(gè)胖子當(dāng)著我的面吹牛亡嫌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掘而,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼挟冠,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袍睡?” 一聲冷哼從身側(cè)響起知染,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎斑胜,沒想到半個(gè)月后控淡,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡止潘,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年掺炭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凭戴。...
    茶點(diǎn)故事閱讀 39,703評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡涧狮,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情者冤,我是刑警寧澤肤视,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站涉枫,受9級特大地震影響邢滑,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜拜银,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一殊鞭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尼桶,春花似錦操灿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至小腊,卻和暖如春救鲤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秩冈。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工本缠, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人入问。 一個(gè)月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓丹锹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親芬失。 傳聞我的和親對象是個(gè)殘疾皇子楣黍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,601評論 2 353

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,072評論 25 707
  • 用到的組件 1、通過CocoaPods安裝 2棱烂、第三方類庫安裝 3租漂、第三方服務(wù) 友盟社會化分享組件 友盟用戶反饋 ...
    SunnyLeong閱讀 14,613評論 1 180
  • 成吉思汗,作為一個(gè)戰(zhàn)士颊糜,和匈奴阿提拉一樣野蠻哩治;作為一個(gè)統(tǒng)治者和組織者,他比后者更為偉大衬鱼;他所征服的地方更寬廣锚扎,勝利...
    云丹風(fēng)卿閱讀 153評論 0 0
  • Excel中選擇(選定)可見單元格的方法介紹 我們分兩個(gè)版本來介紹選擇(選定)可見單元格的方法。 第一馁启, Exce...
    oo水桶oo閱讀 9,759評論 0 0
  • 本來想著每天以寫日記的方式來這里記錄一些東西,但直到現(xiàn)在才真正動筆可見我的拖延癥已經(jīng)深入骨髓了。 不知道從...
    shan可徐徐歸yi閱讀 368評論 1 2