WEBAPP开发之移动端webapp点词翻译的设计与实现
白羽 2018-08-13 来源 :网络 阅读 1229 评论 0

摘要:本文将带你了解WEBAPP开发之移动端webapp点词翻译的设计与实现,希望本文对大家学WEBAPP有所帮助。

        本文将带你了解WEBAPP开发之移动端webapp点词翻译的设计与实现,希望本文对大家学WEBAPP有所帮助。




单词翻译常见于APP中,那么在网页中对于一段中英混杂的内容怎么准确的做到单词的翻译呢?

我要渲染的内容是一段段的html,用react渲染一段html内容是没有什么难度,使用dangerouslySetInnerHTML即可。但是可以做到将内容中的英文单词翻译出来,是怎么实现的呢?一起来看一下吧。
效果




事情是这样的...
我前端是做内容展示,后台将Html格式的内容传递到前端,前端原生元素的dangerouslySetInnerHTML属性去解析html内容,就可以使用react框架渲染html了



仔细看,这个属性用的是{{}}2个括号而不是1个括号。原因是:第一{}代表jsx语法开始,第二个是代表dangerouslySetInnerHTML接收的是一个对象键值对。它接收的内容是html的,很容易收到XSS攻击,所以这个属性有了dangerous这个单词...
过程

重组英文单词
后台传给我的一段一段的内容是这样的:





既然要提取出来做单词翻译,就得有能力去获取每一个单词,所以我的打算是,把内容提取出来,是一个英文单词就放进一个span标签中。但是这一步在哪里处理比较好呢,我想了想,在页面渲染之前处理吧,这样页面渲染的压力要减小,提高渲染速度。所以我在前端接收到后端发送的数据之后,在存入store之前就先处理好。
case"OBT_BOOK_CONTENT_SUCCESS":
varnewContents=action.meta.bookcontent.map((item,index)=>{
item.paragraphContent=item.paragraphContent.replace(/src="/g,`src="${url}`);
//处理caseContent中的单词
vardiv=document.createElement('div');
div.innerHTML=item.paragraphContent;
varcaseContent=div.querySelector('.caseContent');

if(caseContent){
vararr=caseContent.innerText.split("");
for(vari=0;i<arr.length;i++){
arr[i]=""+arr[i]+""
}
caseContent.innerHTML=arr.join("");
item.paragraphContent=div.innerHTML;
}
returnitem;
})
returnObject.assign({},state,{
bookcontent:newContents
})

由于传给我的是一大段内容,里面的元素的类型不只一种、类名也不止一种,有div.caseTitle.caseContentstrong等等,但是我只处理面积最大的一块英文,也就是只处理caseContent中的英文单词这就好办了。我没有用string的方法,去查找这个串在什么位置,怎么截取怎么拼接。没有。我利用了DOM的原理,借助DOM原生的api帮助我得到我要的英文单词。我创建了一个div(没有DOM我就自己创建DOM咯),然后DOM查找.caseContent,用空格把其中的所有单词提取出来,再给每一个单词用span包起来,然后把.caseContent中的内容替换掉,同时div的innerHTML也就变了,最后改变paragraphContent。就这样把后端传过来的东西做了修改,再使用。

提取单词
由于我想要翻译的单词是用span包裹的,所以我需要检查用户点击屏幕所在的节点是不是span

if(e.target.nodeName==='SPAN'){
vars="";
if(e.target.innerText){
varlen=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;
}
varchooseSpan=e.target;

this.props.checkWords(s,chooseSpan);
}
}
console.log(s);
}

利用正则!/^[\u4e00-\u9fa5]{0,}$/提取出来英文单词,但是有些单词末尾会带着英文状态下的逗号,句号.,所以还需要用substring剪切一下单词,再调用方法。
这里,提取页面中点击的内容,需要CSS的配合。
user-select:text;

user-selct:text;可以让页面中的内容被选中。而user-select:none是让页面中的内容不被选中。
-ms-user-select:none;
-webkit-user-select:none;
user-select:none;

获取了单词s之后,还需要做一点交互,就是被选中的单词高亮起来,所有,span元素也需要被处理,为了严谨,所以需要再判断是不是单词,是的话,再对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方法中调用了查单词的api,我用的是有道智云的api,需要自己注册一个账号,然后申请一个应用。获取appKey和appSecret,设置好from和to的值,也就是你要从什么语言转什么语言,准备一个随机数salt,然后各种生成签名一波操作。

varappSecret='GOPjZoiSnH592P31Qn6xoallHn3zUnSh';
varappKey='06fc15a9c06cb290';
varsalt=''+(newDate).getTime();
//多个query可以用\n连接如query='apple\norange\nbanana\npear'
varfrom='en';
varto='zh-CHS';
varstr1=appKey+q+salt+appSecret;
vardata=null;
varsign=md5(str1);
varsendRes=res;
sign=sign.toUpperCase();
q=encodeURI(q);
varurl=`//openapi.youdao.com/api?q=${q}&from=${from}&to=${to}&appKey=${appKey}&salt=${salt}&sign=${sign}`

有了这个url之后,就可以请求了。返回的东西是:





image

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




后来发现扇贝的单词api做的也不错,没有有道用的这么麻烦,有道还需要签名,用户量大的时候也会有限制,准备以后换扇贝的。
完毕
至此,使用react框架完成移动页面的定向单词翻译已完成。


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之WebApp频道!

本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程