更新 translate.js 为最新 v3.12.4.20250110 版本,修复控制台报错 TypeError: Cannot read

properties of undefined (reading 'appendChild')
(注意,我用在线的测试过,完美没问题,但是本地开发不会vue每安装环境所以并没有实际编译运行测试,还需要简单试一下)
This commit is contained in:
鬼画符 2025-01-10 14:38:03 +08:00
parent 9f08846531
commit 5f2d12f5dd
2 changed files with 1001 additions and 484 deletions

View File

@ -275,10 +275,10 @@
translate.service.use('client.edge')
//开启html页面变化的监控对变化部分会进行自动翻译
translate.listener.start()
//不显示语言选择标签
translate.selectLanguageTag.show = false;
//执行翻译初始化操作显示出select语言选择
translate.execute()
//不显示语言选择标签
translate.selectLanguageTag.show = false
</script>
</head>

View File

@ -6,11 +6,19 @@
*/
var translate = {
/*
/**
* 当前的版本
* npm 脚本自动更新无需手动修改
* 格式major.minor.patch.date
*/
version:'3.5.2.20240613',
useVersion:'v2', //当前使用的版本默认使用v2. 可使用 setUseVersion2(); //来设置使用v2 已废弃主要是区分是否是v1版本来着v2跟v3版本是同样的使用方式
// AUTO_VERSION_START
version: '3.12.4.20250110',
// AUTO_VERSION_END
/*
当前使用的版本默认使用v2. 可使用 setUseVersion2();
来设置使用v2 已废弃主要是区分是否是v1版本来着v2跟v3版本是同样的使用方式
*/
useVersion:'v2',
setUseVersion2:function(){
translate.useVersion = 'v2';
console.log('提示 v2.10 之后的版本默认就是使用V2版本当前版本为:'+translate.version+' translate.setUseVersion2() 可以不用再加这一行了当然加了也无所谓只是加了跟不加是完全一样的');
@ -140,7 +148,12 @@ var translate = {
//判断translate 的id是否存在不存在就创建一个
if(document.getElementById(translate.selectLanguageTag.documentId) == null){
var body_trans = document.getElementsByTagName('body')[0];
var findBody = document.getElementsByTagName('body');
if(findBody.length == 0){
console.log('body tag not find, translate.selectLanguageTag.render() is not show Select Language');
return;
}
var body_trans = findBody[0];
var div = document.createElement("div"); //创建一个script标签
div.id=translate.selectLanguageTag.documentId;
body_trans.appendChild(div);
@ -446,7 +459,15 @@ var translate = {
}
return false;
}
},
/*
* 忽略不被翻译的文本这里出现的文本将不会被翻译
* 这个其实是借用了 自定义术语 的能力设置了自定义术语的原字符等于翻译后的字符 于是这个字符就不会被翻译了
* 这里可以是多个数组 ['你好','世界']
*/
text:[]
},
//刷新页面你可以自定义刷新页面的方式比如在 uniapp 打包生成 apk apk中的刷新页面就不是h5的这个刷新而是app的刷新方式就需要自己进行重写这个刷新页面的方法了
refreshCurrentPage:function(){
@ -548,6 +569,7 @@ var translate = {
return translate.nomenclature.data;
},
//对传入的str字符进行替换将其中的自定义术语提前进行替换然后将替换后的结果返回
//v3.11 后此方法已废弃不再使用
dispose:function(str){
if(str == null || str.length == 0){
return str;
@ -645,6 +667,7 @@ var translate = {
},
},
office:{
/*
网页上翻译之后自动导出当前页面的术语库
@ -795,7 +818,7 @@ var translate = {
*/
nodeQueue:{},
//指定要翻译的元素的集合,可传入一个元素或多个元素
//如设置一个元素可传入如 document.getElementsById('test')
//如设置一个元素可传入如 document.getElementById('test')
//如设置多个元素可传入如 document.getElementsByTagName('DIV')
setDocuments:function(documents){
if (documents == null || typeof(documents) == 'undefined') {
@ -815,6 +838,7 @@ var translate = {
},
//获取当前指定翻译的元素数组形式 [document,document,...]
//如果用户未使用setDocuments 指定的那么返回整个网页
//它返回的永远是个数组形式
getDocuments:function(){
if(translate.documents != null && typeof(translate.documents) != 'undefined' && translate.documents.length > 0){
// setDocuments 指定的
@ -823,7 +847,9 @@ var translate = {
//未使用 setDocuments指定那就是整个网页了
//return document.all; //翻译所有的 这是 v3.5.0之前的
//v3.5.0 之后采用 html的最上层的demo而不是 document.all 拿到可能几千个dom
return document.documentElement;
var doms = new Array();
doms[0] = document.documentElement;
return doms;
}
},
listener:{
@ -948,8 +974,7 @@ var translate = {
// 创建一个观察器实例并传入回调函数
translate.listener.observer = new MutationObserver(translate.listener.callback);
// 以上述配置开始观察目标节点
var docs = new Array();
docs[0] = translate.getDocuments();
var docs = translate.getDocuments();
for(var docs_index = 0; docs_index < docs.length; docs_index++){
var doc = docs[docs_index];
if(doc != null){
@ -1103,7 +1128,6 @@ var translate = {
}
}, 50, ipnode);
translate.element.nodeAnalyse.set(this.nodes[hash][task_index], task.originalText, task.resultText, task['attribute']);
@ -1266,8 +1290,14 @@ var translate = {
//判断本地语种跟要翻译的目标语种是否一样如果是一样那就不需要进行任何翻译
if(translate.to == translate.language.getLocal()){
if(translate.language.translateLocal){
//这是自定义设置的允许翻译本地语种中跟本地语种不一致的语言进行翻译
}else{
return;
}
}
/********** 翻译进行 */
@ -1302,8 +1332,7 @@ var translate = {
}else{
//23
all = new Array();
all[0] = translate.getDocuments();
all = translate.getDocuments();
}
//console.log('----要翻译的目标元素-----');
//console.log(all)
@ -1708,6 +1737,9 @@ var translate = {
var thhash = translateHashArray[lang][hai];
//取得这个翻译的node
//var ipnode = translate.nodeQueue[uuid]['list'][lang][thhash].nodes[ipni].node;
//console.log('translate.nodeQueue[\''+uuid+'\'][\'list\'][\'chinese_simplified\'][\''+thhash+'\']');
//console.log(lang);
//console.log(translate.nodeQueue[uuid]['list'][lang][thhash].nodes);
for(var ipni = 0; ipni < translate.nodeQueue[uuid]['list'][lang][thhash].nodes.length; ipni++){
//取得这个翻译的node
var ipnode = translate.nodeQueue[uuid]['list'][lang][thhash].nodes[ipni].node;
@ -1851,6 +1883,19 @@ var translate = {
*/
nodeHistory:{},
element:{
/*
注意里面全部的必须小写
第一个是tag第二个是tag的属性比如要翻译 input value 属性那么如下
translate.element.tagAttribute['input']=['value'];
比如要翻译 input value data-value 这两个属性那么如下
translate.element.tagAttribute['input']=['value','data-value'];
有几个要翻译的属性就写上几个
同样有几个要额外翻译的tag就加上几行
详细文档参考 http://translate.zvo.cn/231504.html
*/
tagAttribute : {},
//对翻译前后的node元素的分析翻以前及渲染翻译后
nodeAnalyse:{
/*
@ -1905,11 +1950,16 @@ var translate = {
//替换渲染
if(typeof(originalText) != 'undefined' && originalText.length > 0){
if(typeof(node[attribute]) != 'undefined'){
//这种是主流框架像是vueelementreact 都是用这种 DOM Property 的方式更快
node[attribute] = node[attribute].replace(new RegExp(translate.util.regExp.pattern(originalText),'g'), translate.util.regExp.resultText(resultText));
}else{
console.log(node);
}
//这种 Html Attribute 方式 v3.12 版本之前一直使用的方式速度上要慢于 上面的为了向前兼容不至于升级出问题后面可能会优化掉
var htmlAttributeValue = node.getAttribute(attribute);
if(htmlAttributeValue != null && typeof(htmlAttributeValue) != 'undefined'){
//这个才是在v3.9.2 后要用的上面的留着只是为了适配以前的
node.setAttribute(attribute, htmlAttributeValue.replace(new RegExp(translate.util.regExp.pattern(originalText),'g'), translate.util.regExp.resultText(resultText)));
}
}
return result;
}
@ -1989,7 +2039,12 @@ var translate = {
//meta标签如是关键词描述等
if(typeof(node.name) != 'undefined' && node.name != null){
var nodeAttributeName = node.name.toLowerCase(); //取meta 标签的name 属性
if(nodeAttributeName == 'keywords' || nodeAttributeName == 'description'){
var nodeAttributePropertyOri = node.getAttribute('property'); // property的值
var nodeAttributeProperty = '';
if(typeof(nodeAttributePropertyOri) != 'undefined' && nodeAttributePropertyOri != null && nodeAttributePropertyOri.length > 0){
nodeAttributeProperty = nodeAttributePropertyOri.toLowerCase();
}
if(nodeAttributeName == 'keywords' || nodeAttributeName == 'description' || nodeAttributeName == 'sharetitle' || nodeAttributeProperty == 'og:title' || nodeAttributeProperty == 'og:description' || nodeAttributeProperty == 'og:site_name' || nodeAttributeProperty == 'og:novel:latest_chapter_name'){
//替换渲染
if(typeof(originalText) != 'undefined' && originalText != null && originalText.length > 0){
//this.nodes[hash][task_index].nodeValue = this.nodes[hash][task_index].nodeValue.replace(new RegExp(translate.util.regExp.pattern(task.originalText),'g'), translate.util.regExp.resultText(task.resultText));
@ -2081,7 +2136,51 @@ var translate = {
}
}
//v3.9.2 增加, 用户可自定义标签内 attribute 的翻译
var nodeNameLowerCase = translate.element.getNodeName(node).toLowerCase();
if(typeof(translate.element.tagAttribute[nodeNameLowerCase]) != 'undefined'){
//console.log('find:'+nodeNameLowerCase);
//console.log(translate.element.tagAttribute[nodeNameLowerCase]);
for(var attributeName_index in translate.element.tagAttribute[nodeNameLowerCase]){
var attributeName = translate.element.tagAttribute[nodeNameLowerCase][attributeName_index];
//console.log(attributeName);
//console.log(node.getAttribute(attributeName));
/*
* 默认是 HtmlAtrribute 也就是 HTML特性取值有两个:
* HTMLAtrribute : HTML特性
* DOMProperty : DOM属性
*/
var DOMPropOrHTMLAttr = 'HTMLAtrribute';
var attributeValue = node.getAttribute(attributeName);
if(typeof(attributeValue) == 'undefined' || attributeValue == null){
//vueelementreact 中的一些动态赋值比如 element 中的 el-select 选中后赋予显示出来的文本getAttribute 就取不到因为是改动的 DOM属性所以要用这种方式才能取出来
attributeValue = node[attributeName];
DOMPropOrHTMLAttr = 'DOMProperty';
}
if(typeof(attributeValue) == 'undefined' || attributeValue == null){
//这个tag标签没有这个属性忽略
continue;
}
//if(typeof(node.getAttribute(attributeName)) == 'undefined' && typeof(node[attributeName]) == 'undefined'){
// //这个tag标签没有这个 attribute忽略
// continue
//}
//加入翻译
translate.addNodeToQueue(uuid, node, attributeValue, attributeName);
}
}
var childNodes = node.childNodes;
if(childNodes == null || typeof(childNodes) == 'undefined'){
return;
}
if(childNodes.length > 0){
for(var i = 0; i<childNodes.length; i++){
translate.element.whileNodes(uuid, childNodes[i]);
@ -2095,7 +2194,6 @@ var translate = {
if(node == null || typeof(node) == 'undefined'){
return;
}
//console.log(node)
if(node.parentNode == null){
return;
}
@ -2152,6 +2250,7 @@ var translate = {
//console.log('addNodeToQueue -- '+nodeAnaly['node']+', text:' + nodeAnaly['text']);
translate.addNodeToQueue(uuid, nodeAnaly['node'], nodeAnaly['text']);
}
//console.log(nodeAnaly);
/*
//console.log(node.nodeName+', type:'+node.nodeType+', '+node.nodeValue);
@ -2272,6 +2371,214 @@ var translate = {
}
//console.log(node.nodeValue);
//原本传入的text会被切割为多个小块
var textArray = new Array();
textArray.push(text); //先将主 text 赋予 后面如果对主text进行加工分割分割后会将主text给删除掉
//console.log(textArray);
/**** v3.10.2.20241206 - 增加自定义忽略翻译的文本,忽略翻译的文本不会被翻译 - 当然这样会打乱翻译之后阅读的连贯性 ****/
for(var ti = 0; ti<translate.ignore.text.length; ti++){
if(translate.ignore.text[ti].trim().length == 0){
continue;
}
textArray = translate.addNodeToQueueTextAnalysis(uuid, node, textArray, attribute, translate.ignore.text[ti], translate.ignore.text[ti]);
//console.log(textArray);
}
/**** v3.10.2.20241206 - 自定义术语能力全面优化 - 当然这样会打乱翻译之后阅读的连贯性 ****/
//判断是否进行了翻译也就是有设置目标语种并且跟当前语种不一致
if(typeof(translate.temp_nomenclature) == 'undefined'){
translate.temp_nomenclature = new Array();
}
if(typeof(translate.temp_nomenclature[translate.language.getLocal()]) == 'undefined'){
nomenclatureKeyArray = new Array();
}
if(typeof(translate.nomenclature.data[translate.language.getLocal()]) != 'undefined' && typeof(translate.nomenclature.data[translate.language.getLocal()][translate.to]) != 'undefined'){
var nomenclatureKeyArray;
for(var nomenclatureKey in translate.nomenclature.data[translate.language.getLocal()][translate.to]){
//nomenclatureKey 便是自定义术语的原始文本值是要替换为的文本
//console.log(nomenclatureKey);
//自定义属于的指定的结果字符串
var nomenclatureValue = translate.nomenclature.data[translate.language.getLocal()][translate.to][nomenclatureKey];
textArray = translate.addNodeToQueueTextAnalysis(uuid, node, textArray, attribute, nomenclatureKey, nomenclatureValue);
if(typeof(nomenclatureKeyArray) != 'undefined'){
nomenclatureKeyArray.push(nomenclatureKey);
}
}
if(typeof(translate.temp_nomenclature[translate.language.getLocal()]) == 'undefined'){
translate.temp_nomenclature[translate.language.getLocal()] = nomenclatureKeyArray;
}
}
/**** v3.10.2.20241206 - 自定义术语能力全面优化 - end ****/
for(var tai = 0; tai<textArray.length; tai++){
if(textArray[tai].trim().length == 0){
continue;
}
//判断是否出现在自定义忽略字符串
if(translate.ignore.text.indexOf(textArray[tai].trim()) > -1){
//console.log(textArray[tai]+' 是忽略翻译的文本不翻译');
continue;
}
//判断是否出现在自定义术语的
if(typeof(translate.temp_nomenclature[translate.language.getLocal()]) != 'undefined'){
if(translate.temp_nomenclature[translate.language.getLocal()].indexOf(textArray[tai].trim()) > -1){
//console.log(textArray[tai]+' 是自定义术语不翻译');
continue;
}
}
translate.addNodeToQueueAnalysis(uuid, node, textArray[tai], attribute);
}
//this.nodeQueue[lang][key][this.nodeQueue[lang][key].length]=node; //往数组中追加
},
/**
* 服务于上面的 addNodeToQueue 用于区分不同type情况进行调用此加入 translate.nodeQueue
* uuid, node, attribute 这及个参数说明见 addNodeToQueue 的参数说明相同
* textArray 进行处理的要翻译的文本数组这个最开始只是一个但是命中后分割的多了也就变成多个了
* nomenclatureKey 替换的原始文本也就是自定义术语的key部分
* nomenclatureValue 替换的目标文本也就是自定义术语的value部分 如果 nomenclatureKey = nomenclatureValue 则是自定义忽略翻译的文本这个文本不被翻译
* @return 处理过后的 textArray 如果没有命中则返回的是传入的 textArray 命中了则是切割以及删除原本判断的text之后的 textArray
*/
addNodeToQueueTextAnalysis:function(uuid, node,textArray, attribute, nomenclatureKey, nomenclatureValue){
var deleteTextArray = new Array(); //记录要从 textArray 中删除的字符串
for(var tai = 0; tai<textArray.length; tai++){
var text = textArray[tai];
if(text.trim() == nomenclatureValue.trim()){
//这里是自定义术语被替换后重新扫描时扫出来的那么直接忽略不做任何处理因为自定义术语的结果就是最终结果了
continue;
}
//判断一下原始文本是否有出现在了这个word要翻译的字符串中
var wordKeyIndex = text.indexOf(nomenclatureKey);
if(wordKeyIndex > -1){
//出现了那么需要将其立即进行更改将自定义术语定义的结果渲染到页面中并且将 word 要翻译的字符串中自定义术语部分删除只翻译除了自定义术语剩余的部分
//console.log(text+' --> '+nomenclatureKey);
/*
* 判断一下这个text中出现匹配自定义术语的部分是否是已经被替换过了比如要将 替换为 你好 这里的好会重复替换这里是判断这种情况
* 其中要判断一下 key 不等于value因为key等于value属于是指定这个key不被翻译的情况
*/
if(nomenclatureKey != nomenclatureValue){
var substringStart = wordKeyIndex-nomenclatureValue.length;
if(substringStart < 0){
substringStart = 0;
}
var substringEnd = wordKeyIndex+nomenclatureValue.length;
if(substringEnd > text.length){
substringEnd = text.length;
}
var nomenclatureValueJudgement = text.substring(substringStart, substringEnd);
//console.log(text+', '+nomenclatureValueJudgement);
if(nomenclatureValueJudgement.indexOf(nomenclatureValue) > -1){
//已经替换过了可能会重复替换所以忽略掉
continue;
}
}
//判断当前是否是英语及变种也就是单词之间需要有空格的如果前后没有空格要补充上空格
if(translate.language.wordBlankConnector(translate.to)){
if(wordKeyIndex > 0){
//它前面还有文本判断它前面的文本是否是空格如果不是那么要补充上空格
var before = text.charAt(wordKeyIndex-1);
//console.log(before);
if(!(/\s/.test(before))){
//不是空白字符补充上一个空格用于将两个单词隔开
nomenclatureValue = ' '+nomenclatureValue
}
}
if(wordKeyIndex + nomenclatureKey.length < text.length){
//它后面还有文本判断它前面的文本是否是空格如果不是那么要补充上空格
var after = text.charAt(wordKeyIndex + nomenclatureKey.length);
//console.log(after);
if(!(/\s/.test(before))){
//不是空白字符补充上一个空格用于将两个单词隔开
nomenclatureValue = nomenclatureValue+' ';
}
}
}
//如果是自定义术语的key等于value则是属于指定的某些文本不进行翻译的情况所以这里要单独判断一下
//console.log(nomenclatureKey+':'+nomenclatureValue);
if(nomenclatureKey != nomenclatureValue){
translate.element.nodeAnalyse.set(node, nomenclatureKey, nomenclatureValue, attribute);
}
// text 中将自定义术语的部分删掉自定义术语的不被翻译
var wordSplits = text.split(nomenclatureKey);
var isPushTextArray = false;
for(var index = 0; index < wordSplits.length; index++){
//console.log(index);
var subWord = wordSplits[index]; //分割后的子字符串
if(subWord.trim().length == 0){
continue;
}
//console.log(subWord);
//将其加入 textArray
textArray.push(subWord);
deleteTextArray.push(text);
}
//console.log(wordSplits);
//自定义术语适配完后就直接退出了
//return wordSplits;
}
}
//console.log(deleteTextArray)
// textArray 中删除
if(deleteTextArray.length > 0){
for(var di = 0; di<deleteTextArray.length; di++){
let index = textArray.indexOf(deleteTextArray[di]);
if (index > -1) {
//console.log(textArray);
//console.log(deleteTextArray[di]);
textArray.splice(index, 1);
//console.log(textArray);
}
}
}
return textArray;
},
/*
服务于上面的 addNodeToQueue 用于区分不同type情况进行调用此加入 translate.nodeQueue
uuid, node, attribute 这五个参数说明见 addNodeToQueue 的参数说明相同
word 要实际进行翻译的文本也就是要把它拿来进行通过后端翻译接口进行翻译的文本
lang 当前要翻译的文本的语种 english
beforeText 参见 translate.nodeQueue 注释中第七维的解释
afterText 参见 translate.nodeQueue 注释中第七维的解释
*/
addNodeToQueueAnalysis:function(uuid, node, text, attribute){
//获取当前是什么语种
//var langs = translate.language.get(text);
var textRecognition = translate.language.recognition(text);
@ -2323,6 +2630,7 @@ var translate = {
var beforeText = langs[lang].list[word_index]['beforeText'];
var afterText = langs[lang].list[word_index]['afterText'];
//console.log(lang+' - '+word);
translate.addNodeQueueItem(uuid, node, word, attribute, lang, beforeText, afterText);
/*
@ -2382,12 +2690,11 @@ var translate = {
}else{
//直接翻译整个元素内的内容不再做语种分类首先删除英文然后将出现次数最多的语种作为原本语种
var lang = textRecognition.languageName;
//console.log(lang+' - '+text);
translate.addNodeQueueItem(uuid, node, text, attribute, lang, '', '');
}
//this.nodeQueue[lang][key][this.nodeQueue[lang][key].length]=node; //往数组中追加
},
/*
@ -2406,7 +2713,7 @@ var translate = {
if(translate.nodeQueue[uuid]['list'][lang] == null || typeof(translate.nodeQueue[uuid]['list'][lang]) == 'undefined'){
translate.nodeQueue[uuid]['list'][lang] = new Array();
}
//console.log(word)
//var word = text; //要翻译的文本
var hash = translate.util.hash(word); //要翻译的文本的hash
@ -2424,7 +2731,12 @@ var translate = {
*/
translate.nodeQueue[uuid]['list'][lang][hash]['nodes'] = new Array();
translate.nodeQueue[uuid]['list'][lang][hash]['original'] = word;
translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = translate.nomenclature.dispose(word); //自定义术语处理
//自定义术语处理在此前面已经执行过了所以这个废弃不需要处理自定义术语部分了
//translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = translate.nomenclature.dispose(word);
translate.nodeQueue[uuid]['list'][lang][hash]['translateText'] = word;
//console.log(word)
//其中key nodes 是第四维数组里面存放具体的node元素对象
}
@ -2578,6 +2890,14 @@ var translate = {
//当前本地语种本地语言默认是简体中文设置请使用 translate.language.setLocal(...)不可直接使用使用需用 getLocal()
local:'',
/*
* v3.12增加, 是否会翻译本地语种默认是false不会翻译
* 比如当前设置的本地语种是简体中文 但是网页中也有一段英文 如果设置了translate.to 为中文也就是要以中文显示 默认是false的情况下整个页面是不会被任何翻译的也就是有的那段英文也不会进行任何翻译依旧是显示英文
* 如果这里设置为 true 则英文也会被翻译只要不是中文的都会被翻译为要显示的语种也就是都会被翻译为中文
*/
translateLocal:false,
/*
翻译语种范围
比如传入 ['chinese_simplified','chinese_traditional','english'] 则表示仅对网页中的简体中文繁体中文英文 进行翻译而网页中出现的其他的像是法语韩语则不会进行翻译
@ -3242,7 +3562,7 @@ var translate = {
return true;
},
//繁体中文的字典判断繁体中文就是通过此判断
chinese_traditional_dict: '皚藹礙愛翺襖奧壩罷擺敗頒辦絆幫綁鎊謗剝飽寶報鮑輩貝鋇狽備憊繃筆畢斃閉邊編貶變辯辮鼈癟瀕濱賓擯餅撥缽鉑駁蔔補參蠶殘慚慘燦蒼艙倉滄廁側冊測層詫攙摻蟬饞讒纏鏟産闡顫場嘗長償腸廠暢鈔車徹塵陳襯撐稱懲誠騁癡遲馳恥齒熾沖蟲寵疇躊籌綢醜櫥廚鋤雛礎儲觸處傳瘡闖創錘純綽辭詞賜聰蔥囪從叢湊竄錯達帶貸擔單鄲撣膽憚誕彈當擋黨蕩檔搗島禱導盜燈鄧敵滌遞締點墊電澱釣調諜疊釘頂錠訂東動棟凍鬥犢獨讀賭鍍鍛斷緞兌隊對噸頓鈍奪鵝額訛惡餓兒爾餌貳發罰閥琺礬釩煩範販飯訪紡飛廢費紛墳奮憤糞豐楓鋒風瘋馮縫諷鳳膚輻撫輔賦複負訃婦縛該鈣蓋幹趕稈贛岡剛鋼綱崗臯鎬擱鴿閣鉻個給龔宮鞏貢鈎溝構購夠蠱顧剮關觀館慣貫廣規矽歸龜閨軌詭櫃貴劊輥滾鍋國過駭韓漢閡鶴賀橫轟鴻紅後壺護滬戶嘩華畫劃話懷壞歡環還緩換喚瘓煥渙黃謊揮輝毀賄穢會燴彙諱誨繪葷渾夥獲貨禍擊機積饑譏雞績緝極輯級擠幾薊劑濟計記際繼紀夾莢頰賈鉀價駕殲監堅箋間艱緘繭檢堿鹼揀撿簡儉減薦檻鑒踐賤見鍵艦劍餞漸濺澗漿蔣槳獎講醬膠澆驕嬌攪鉸矯僥腳餃繳絞轎較稭階節莖驚經頸靜鏡徑痙競淨糾廄舊駒舉據鋸懼劇鵑絹傑潔結誡屆緊錦僅謹進晉燼盡勁荊覺決訣絕鈞軍駿開凱顆殼課墾懇摳庫褲誇塊儈寬礦曠況虧巋窺饋潰擴闊蠟臘萊來賴藍欄攔籃闌蘭瀾讕攬覽懶纜爛濫撈勞澇樂鐳壘類淚籬離裏鯉禮麗厲勵礫曆瀝隸倆聯蓮連鐮憐漣簾斂臉鏈戀煉練糧涼兩輛諒療遼鐐獵臨鄰鱗凜賃齡鈴淩靈嶺領餾劉龍聾嚨籠壟攏隴樓婁摟簍蘆盧顱廬爐擄鹵虜魯賂祿錄陸驢呂鋁侶屢縷慮濾綠巒攣孿灤亂掄輪倫侖淪綸論蘿羅邏鑼籮騾駱絡媽瑪碼螞馬罵嗎買麥賣邁脈瞞饅蠻滿謾貓錨鉚貿麽黴沒鎂門悶們錳夢謎彌覓綿緬廟滅憫閩鳴銘謬謀畝鈉納難撓腦惱鬧餒膩攆撚釀鳥聶齧鑷鎳檸獰甯擰濘鈕紐膿濃農瘧諾歐鷗毆嘔漚盤龐國愛賠噴鵬騙飄頻貧蘋憑評潑頗撲鋪樸譜臍齊騎豈啓氣棄訖牽扡釺鉛遷簽謙錢鉗潛淺譴塹槍嗆牆薔強搶鍬橋喬僑翹竅竊欽親輕氫傾頃請慶瓊窮趨區軀驅齲顴權勸卻鵲讓饒擾繞熱韌認紉榮絨軟銳閏潤灑薩鰓賽傘喪騷掃澀殺紗篩曬閃陝贍繕傷賞燒紹賒攝懾設紳審嬸腎滲聲繩勝聖師獅濕詩屍時蝕實識駛勢釋飾視試壽獸樞輸書贖屬術樹豎數帥雙誰稅順說碩爍絲飼聳慫頌訟誦擻蘇訴肅雖綏歲孫損筍縮瑣鎖獺撻擡攤貪癱灘壇譚談歎湯燙濤縧騰謄銻題體屜條貼鐵廳聽烴銅統頭圖塗團頹蛻脫鴕馱駝橢窪襪彎灣頑萬網韋違圍爲濰維葦偉僞緯謂衛溫聞紋穩問甕撾蝸渦窩嗚鎢烏誣無蕪吳塢霧務誤錫犧襲習銑戲細蝦轄峽俠狹廈鍁鮮纖鹹賢銜閑顯險現獻縣餡羨憲線廂鑲鄉詳響項蕭銷曉嘯蠍協挾攜脅諧寫瀉謝鋅釁興洶鏽繡虛噓須許緒續軒懸選癬絢學勳詢尋馴訓訊遜壓鴉鴨啞亞訝閹煙鹽嚴顔閻豔厭硯彥諺驗鴦楊揚瘍陽癢養樣瑤搖堯遙窯謠藥爺頁業葉醫銥頤遺儀彜蟻藝億憶義詣議誼譯異繹蔭陰銀飲櫻嬰鷹應纓瑩螢營熒蠅穎喲擁傭癰踴詠湧優憂郵鈾猶遊誘輿魚漁娛與嶼語籲禦獄譽預馭鴛淵轅園員圓緣遠願約躍鑰嶽粵悅閱雲鄖勻隕運蘊醞暈韻雜災載攢暫贊贓髒鑿棗竈責擇則澤賊贈紮劄軋鍘閘詐齋債氈盞斬輾嶄棧戰綻張漲帳賬脹趙蟄轍鍺這貞針偵診鎮陣掙睜猙幀鄭證織職執紙摯擲幟質鍾終種腫衆謅軸皺晝驟豬諸誅燭矚囑貯鑄築駐專磚轉賺樁莊裝妝壯狀錐贅墜綴諄濁茲資漬蹤綜總縱鄒詛組鑽緻鐘麼為隻兇準啟闆裡靂餘鍊',
chinese_traditional_dict: '皚藹礙愛翺襖奧壩罷擺敗頒辦絆幫綁鎊謗剝飽寶報鮑輩貝鋇狽備憊繃筆畢斃閉邊編貶變辯辮鼈癟瀕濱賓擯餅撥缽鉑駁蔔補參蠶殘慚慘燦蒼艙倉滄廁側冊測層詫攙摻蟬饞讒纏鏟産闡顫場嘗長償腸廠暢鈔車徹塵陳襯撐稱懲誠騁癡遲馳恥齒熾沖蟲寵疇躊籌綢醜櫥廚鋤雛礎儲觸處傳瘡闖創錘純綽辭詞賜聰蔥囪從叢湊竄錯達帶貸擔單鄲撣膽憚誕彈當擋黨蕩檔搗島禱導盜燈鄧敵滌遞締點墊電澱釣調諜疊釘頂錠訂東動棟凍鬥犢獨讀賭鍍鍛斷緞兌隊對噸頓鈍奪鵝額訛惡餓兒爾餌貳發罰閥琺礬釩煩範販飯訪紡飛廢費紛墳奮憤糞豐楓鋒風瘋馮縫諷鳳膚輻撫輔賦複負訃婦縛該鈣蓋幹趕稈贛岡剛鋼綱崗臯鎬擱鴿閣鉻個給龔宮鞏貢鈎溝構購夠蠱顧剮關觀館慣貫廣規矽歸龜閨軌詭櫃貴劊輥滾鍋國過駭韓漢閡鶴賀橫轟鴻紅後壺護滬戶嘩華畫劃話懷壞歡環還緩換喚瘓煥渙黃謊揮輝毀賄穢會燴彙諱誨繪葷渾夥獲貨禍擊機積饑譏雞績緝極輯級擠幾薊劑濟計記際繼紀夾莢頰賈鉀價駕殲監堅箋間艱緘繭檢堿鹼揀撿簡儉減薦檻鑒踐賤見鍵艦劍餞漸濺澗漿蔣槳獎講醬膠澆驕嬌攪鉸矯僥腳餃繳絞轎較稭階節莖驚經頸靜鏡徑痙競淨糾廄舊駒舉據鋸懼劇鵑絹傑潔結誡屆緊錦僅謹進晉燼盡勁荊覺決訣絕鈞軍駿開凱顆殼課墾懇摳庫褲誇塊儈寬礦曠況虧巋窺饋潰擴闊蠟臘萊來賴藍欄攔籃闌蘭瀾讕攬覽懶纜爛濫撈勞澇樂鐳壘類淚籬離裏鯉禮麗厲勵礫曆瀝隸倆聯蓮連鐮憐漣簾斂臉鏈戀煉練糧涼兩輛諒療遼鐐獵臨鄰鱗凜賃齡鈴淩靈嶺領餾劉龍聾嚨籠壟攏隴樓婁摟簍蘆盧顱廬爐擄鹵虜魯賂祿錄陸驢呂鋁侶屢縷慮濾綠巒攣孿灤亂掄輪倫侖淪綸論蘿羅邏鑼籮騾駱絡媽瑪碼螞馬罵嗎買麥賣邁脈瞞饅蠻滿謾貓錨鉚貿麽黴沒鎂門悶們錳夢謎彌覓綿緬廟滅憫閩鳴銘謬謀畝鈉納難撓腦惱鬧餒膩攆撚釀鳥聶齧鑷鎳檸獰甯擰濘鈕紐膿濃農瘧諾歐鷗毆嘔漚盤龐國愛賠噴鵬騙飄頻貧蘋憑評潑頗撲鋪樸譜臍齊騎豈啓氣棄訖牽扡釺鉛遷簽謙錢鉗潛淺譴塹槍嗆牆薔強搶鍬橋喬僑翹竅竊欽親輕氫傾頃請慶瓊窮趨區軀驅齲顴權勸卻鵲讓饒擾繞熱韌認紉榮絨軟銳閏潤灑薩鰓賽傘喪騷掃澀殺紗篩曬閃陝贍繕傷賞燒紹賒攝懾設紳審嬸腎滲聲繩勝聖師獅濕詩屍時蝕實識駛勢釋飾視試壽獸樞輸書贖屬術樹豎數帥雙誰稅順說碩爍絲飼聳慫頌訟誦擻蘇訴肅雖綏歲孫損筍縮瑣鎖獺撻擡攤貪癱灘壇譚談歎湯燙濤縧騰謄銻題體屜條貼鐵廳聽烴銅統頭圖塗團頹蛻脫鴕馱駝橢窪襪彎灣頑萬網韋違圍爲濰維葦偉僞緯謂衛溫聞紋穩問甕撾蝸渦窩嗚鎢烏誣無蕪吳塢霧務誤錫犧襲習銑戲細蝦轄峽俠狹廈鍁鮮纖鹹賢銜閑顯險現獻縣餡羨憲線廂鑲鄉詳響項蕭銷曉嘯蠍協挾攜脅諧寫瀉謝鋅釁興洶鏽繡虛噓須許緒續軒懸選癬絢學勳詢尋馴訓訊遜壓鴉鴨啞亞訝閹煙鹽嚴顔閻豔厭硯彥諺驗鴦楊揚瘍陽癢養樣瑤搖堯遙窯謠藥爺頁業葉醫銥頤遺儀彜蟻藝億憶義詣議誼譯異繹蔭陰銀飲櫻嬰鷹應纓瑩螢營熒蠅穎喲擁傭癰踴詠湧優憂郵鈾猶遊誘輿魚漁娛與嶼語籲禦獄譽預馭鴛淵轅園員圓緣遠願約躍鑰嶽粵悅閱雲鄖勻隕運蘊醞暈韻雜災載攢暫贊贓髒鑿棗竈責擇則澤賊贈紮劄軋鍘閘詐齋債氈盞斬輾嶄棧戰綻張漲帳賬脹趙蟄轍鍺這貞針偵診鎮陣掙睜猙幀鄭證織職執紙摯擲幟質鍾終種腫衆謅軸皺晝驟豬諸誅燭矚囑貯鑄築駐專磚轉賺樁莊裝妝壯狀錐贅墜綴諄濁茲資漬蹤綜總縱鄒詛組鑽緻鐘麼為隻兇準啟闆裡靂餘鍊',
/*
中文判断
返回
@ -3289,8 +3609,8 @@ var translate = {
},
//是否包含俄语
russian:function(str){
//判断字符有 БВДЖЗИЙКЛМНОПСТУФХЦЧШЩЪЫЬЮЯЇІ
if(/.*[\u0411\u0412\u0414\u0416\u0417\u0418\u0419\u041A\u041B\u041C\u041D\u041E\u041F\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042E\u042F\u0407\u0406]+.*$/.test(str)){
//判断字符有 БВДЖЗИЙЛМНОПСТУФХЦЧШЩЪЫЬЮЯЇІ
if(/.*[\u0411\u0412\u0414\u0416\u0417\u0418\u0419\u041B\u041C\u041D\u041E\u041F\u0421\u0422\u0423\u0424\u0425\u0426\u0427\u0428\u0429\u042A\u042B\u042C\u042E\u042F\u0407\u0406]+.*$/.test(str)){
return true
} else {
return false;
@ -3304,7 +3624,7 @@ var translate = {
return false;
},
//是否包含特殊字符
//是否包含特殊字符包含则是true
specialCharacter:function(str){
//
if(/.*[\u2460-\u24E9]+.*$/.test(str)){
@ -3372,71 +3692,18 @@ var translate = {
U+003D = 等于号
U+003E > 大于符号
U+003F ? 问号
U+0040 @ 英文at的简写符号
U+0041 A 拉丁字母 A
U+0042 B 拉丁字母 B
U+0043 C 拉丁字母 C
U+0044 D 拉丁字母 D
U+0045 E 拉丁字母 E
U+0046 F 拉丁字母 F
U+0047 G 拉丁字母 G
U+0048 H 拉丁字母 H
U+0049 I 拉丁字母 I
U+004A J 拉丁字母 J
U+004B K 拉丁字母 K
U+004C L 拉丁字母 L
U+004D M 拉丁字母 M
U+004E N 拉丁字母 N
U+004F O 拉丁字母 O
U+0050 P 拉丁字母 P
U+0051 Q 拉丁字母 Q
U+0052 R 拉丁字母 R
U+0053 S 拉丁字母 S
U+0054 T 拉丁字母 T
U+0055 U 拉丁字母 U
U+0056 V 拉丁字母 V
U+0057 W 拉丁字母 W
U+0058 X 拉丁字母 X
U+0059 Y 拉丁字母 Y
U+005A Z 拉丁字母 Z
U+005B [ 方括号
U+005C \ 右斜杠
U+005D ] 方括号
U+005E ^ 抑扬重音符号
U+005F _ 底线
U+0060 ` 重音符
U+0061 a 拉丁字母 a
U+0062 b 拉丁字母 b
U+0063 c 拉丁字母 c
U+0064 d 拉丁字母 d
U+0065 e 拉丁字母 e
U+0066 f 拉丁字母 f
U+0067 g 拉丁字母 g
U+0068 h 拉丁字母 h
U+0069 i 拉丁字母 i
U+006A j 拉丁字母 j
U+006B k 拉丁字母 k
U+006C l 拉丁字母 lL的小写
U+006D m 拉丁字母 m
U+006E n 拉丁字母 n
U+006F o 拉丁字母 o
U+0070 p 拉丁字母 p
U+0071 q 拉丁字母 q
U+0072 r 拉丁字母 r
U+0073 s 拉丁字母 s
U+0074 t 拉丁字母 t
U+0075 u 拉丁字母 u
U+0076 v 拉丁字母 v
U+0077 w 拉丁字母 w
U+0078 x 拉丁字母 x
U+0079 y 拉丁字母 y
U+007A z 拉丁字母 z
U+007B { 左花括号
U+007C | 直线
U+007D } 右花括号
U+007E ~ 波浪纹
*/
if(/.*[\u003A-\u007E]+.*$/.test(str)){
if(/.*[\u003B\u003B\u003C\u003D\u003E\u003F\u005B\u005C\u005D\u005E\u005F\u0060\u007B\u007C\u007D\u007E]+.*$/.test(str)){
return true;
}
@ -3586,6 +3853,14 @@ var translate = {
//用户第一次打开网页时自动判断当前用户所在国家使用的是哪种语言来自动进行切换为用户所在国家的语种
//如果使用后第二次在用那就优先以用户所选择的为主
executeByLocalLanguage:function(){
//先读用户自己浏览器的默认语言
var browserDefaultLanguage = translate.util.browserDefaultLanguage();
if(typeof(browserDefaultLanguage) != 'undefined' && browserDefaultLanguage.length > 0){
translate.changeLanguage(browserDefaultLanguage);
return;
}
//如果用户浏览器没读到默认语言或者默认语言没有对应到translate.js支持的语种那么在采用ip识别的方式
translate.request.post(translate.request.api.ip, {}, function(data){
//console.log(data);
if(data.result == 0){
@ -3911,8 +4186,148 @@ var translate = {
}
}
return list;
},
/*
浏览器的语种标识跟translate.js的语种标识的对应
key: 浏览器的语种标识
value: translate.js 的语种标识
*/
browserLanguage:{
'zh-CN':'chinese_simplified',
'zh-TW':'chinese_traditional',
'zh-HK':'chinese_traditional',
'co':'corsican',
'gn':'guarani',
'rw':'kinyarwanda',
'ha':'hausa',
'no':'norwegian',
'nl':'dutch',
'yo':'yoruba',
'en':'english',
'kok':'gongen',
'la':'latin',
'ne':'nepali',
'fr':'french',
'cs':'czech',
'haw':'hawaiian',
'ka':'georgian',
'ru':'russian',
'fa':'persian',
'bho':'bhojpuri',
'hi':'hindi',
'be':'belarusian',
'sw':'swahili',
'is':'icelandic',
'yi':'yiddish',
'tw':'twi',
'ga':'irish',
'gu':'gujarati',
'km':'khmer',
'sk':'slovak',
'he':'hebrew',
'kn':'kannada',
'hu':'hungarian',
'ta':'tamil',
'ar':'arabic',
'bn':'bengali',
'az':'azerbaijani',
'sm':'samoan',
'af':'afrikaans',
'id':'indonesian',
'da':'danish',
'sn':'shona',
'bm':'bambara',
'lt':'lithuanian',
'vi':'vietnamese',
'mt':'maltese',
'tk':'turkmen',
'as':'assamese',
'ca':'catalan',
'si':'singapore',
'ceb':'cebuano',
'gd':'scottish-gaelic',
'sa':'sanskrit',
'pl':'polish',
'gl':'galician',
'lv':'latvian',
'uk':'ukrainian',
'tt':'tatar',
'cy':'welsh',
'ja':'japanese',
'fil':'filipino',
'ay':'aymara',
'lo':'lao',
'te':'telugu',
'ro':'romanian',
'ht':'haitian_creole',
'doi':'dogrid',
'sv':'swedish',
'mai':'maithili',
'th':'thai',
'hy':'armenian',
'my':'burmese',
'ps':'pashto',
'hmn':'hmong',
'dv':'dhivehi',
'lb':'luxembourgish',
'sd':'sindhi',
'ku':'kurdish',
'tr':'turkish',
'mk':'macedonian',
'bg':'bulgarian',
'ms':'malay',
'lg':'luganda',
'mr':'marathi',
'et':'estonian',
'ml':'malayalam',
'de':'deutsch',
'sl':'slovene',
'ur':'urdu',
'pt':'portuguese',
'ig':'igbo',
'ckb':'kurdish_sorani',
'om':'oromo',
'el':'greek',
'es':'spanish',
'fy':'frisian',
'so':'somali',
'am':'amharic',
'ny':'nyanja',
'pa':'punjabi',
'eu':'basque',
'it':'italian',
'sq':'albanian',
'ko':'korean',
'tg':'tajik',
'fi':'finnish',
'ky':'kyrgyz',
'ee':'ewe',
'hr':'croatian',
'kri':'creole',
'qu':'quechua',
'bs':'bosnian',
'mi':'maori'
},
/*
获取浏览器中设置的默认使用语言
返回的是 translate.js 的语言唯一标识
如果返回的是空字符串则是没有匹配到可能是没有获取到本地语言也可能是本地语言跟translate.js 翻译通道没有对应上
*/
browserDefaultLanguage:function(){
var language = navigator.language || navigator.userLanguage;
if(typeof(language) == 'string' && language.length > 0){
var tLang = translate.util.browserLanguage[language];
if(typeof(tLang) == 'undefined'){
//没有在里面
console.log('browser default language : '+language +', translate.js current translate channel not support this language ');
}else{
return tLang;
}
}
//将其转化为 translate.js 的语言id比如简体中文是 chinese_simplified 英语是 english
return '';
}
},
//机器翻译采用哪种翻译服务
service:{
@ -3923,11 +4338,16 @@ var translate = {
*/
name:'translate.service',
/*
其实就是设置 translate.service.name
*/
use: function(serviceName){
if(translate.enterprise.isUse == true){
console.log('您已启用了企业级翻译通道 translate.enterprise.use(); (文档https://translate.zvo.cn/4087.html) , 所以您设置的 translate.service.use(\''+serviceName+'\'); (文档https://translate.zvo.cn/4081.html) 将失效不起作用有企业级翻译通道全部接管');
return;
}
if(typeof(serviceName) == 'string' && serviceName == 'client.edge'){
translate.service.name = serviceName;
@ -3943,7 +4363,7 @@ var translate = {
},
language:{
json:[{"id":"ukrainian","name":"УкраїнськаName","serviceId":"uk"},{"id":"norwegian","name":"Norge","serviceId":"no"},{"id":"welsh","name":"color name","serviceId":"cy"},{"id":"dutch","name":"nederlands","serviceId":"nl"},{"id":"japanese","name":"しろうと","serviceId":"ja"},{"id":"filipino","name":"Pilipino","serviceId":"fil"},{"id":"english","name":"English","serviceId":"en"},{"id":"lao","name":"ກະຣຸນາ","serviceId":"lo"},{"id":"telugu","name":"తెలుగుQFontDatabase","serviceId":"te"},{"id":"romanian","name":"Română","serviceId":"ro"},{"id":"nepali","name":"नेपालीName","serviceId":"ne"},{"id":"french","name":"Français","serviceId":"fr"},{"id":"haitian_creole","name":"Kreyòl ayisyen","serviceId":"ht"},{"id":"czech","name":"český","serviceId":"cs"},{"id":"swedish","name":"Svenska","serviceId":"sv"},{"id":"russian","name":"Русский язык","serviceId":"ru"},{"id":"malagasy","name":"Malagasy","serviceId":"mg"},{"id":"burmese","name":"ဗာရမ်","serviceId":"my"},{"id":"pashto","name":"پښتوName","serviceId":"ps"},{"id":"thai","name":"คนไทย","serviceId":"th"},{"id":"armenian","name":"Արմենյան","serviceId":"hy"},{"id":"chinese_simplified","name":"简体中文","serviceId":"zh-CHS"},{"id":"persian","name":"Persian","serviceId":"fa"},{"id":"chinese_traditional","name":"繁體中文","serviceId":"zh-CHT"},{"id":"kurdish","name":"Kurdî","serviceId":"ku"},{"id":"turkish","name":"Türkçe","serviceId":"tr"},{"id":"hindi","name":"हिन्दी","serviceId":"hi"},{"id":"bulgarian","name":"български","serviceId":"bg"},{"id":"malay","name":"Malay","serviceId":"ms"},{"id":"swahili","name":"Kiswahili","serviceId":"sw"},{"id":"oriya","name":"ଓଡିଆ","serviceId":"or"},{"id":"icelandic","name":"ÍslandName","serviceId":"is"},{"id":"irish","name":"Íris","serviceId":"ga"},{"id":"khmer","name":"ខ្មែរKCharselect unicode block name","serviceId":"km"},{"id":"gujarati","name":"ગુજરાતી","serviceId":"gu"},{"id":"slovak","name":"Slovenská","serviceId":"sk"},{"id":"kannada","name":"ಕನ್ನಡ್Name","serviceId":"kn"},{"id":"hebrew","name":"היברית","serviceId":"he"},{"id":"hungarian","name":"magyar","serviceId":"hu"},{"id":"marathi","name":"मराठीName","serviceId":"mr"},{"id":"tamil","name":"தாமில்","serviceId":"ta"},{"id":"estonian","name":"eesti keel","serviceId":"et"},{"id":"malayalam","name":"മലമാലം","serviceId":"ml"},{"id":"inuktitut","name":"ᐃᓄᒃᑎᑐᑦ","serviceId":"iu"},{"id":"arabic","name":"بالعربية","serviceId":"ar"},{"id":"deutsch","name":"Deutsch","serviceId":"de"},{"id":"slovene","name":"slovenščina","serviceId":"sl"},{"id":"bengali","name":"বেঙ্গালী","serviceId":"bn"},{"id":"urdu","name":"اوردو","serviceId":"ur"},{"id":"azerbaijani","name":"azerbaijani","serviceId":"az"},{"id":"portuguese","name":"português","serviceId":"pt"},{"id":"samoan","name":"lifiava","serviceId":"sm"},{"id":"afrikaans","name":"afrikaans","serviceId":"af"},{"id":"tongan","name":"汤加语","serviceId":"to"},{"id":"greek","name":"ελληνικά","serviceId":"el"},{"id":"indonesian","name":"IndonesiaName","serviceId":"id"},{"id":"spanish","name":"Español","serviceId":"es"},{"id":"danish","name":"dansk","serviceId":"da"},{"id":"amharic","name":"amharic","serviceId":"am"},{"id":"punjabi","name":"ਪੰਜਾਬੀName","serviceId":"pa"},{"id":"albanian","name":"albanian","serviceId":"sq"},{"id":"lithuanian","name":"Lietuva","serviceId":"lt"},{"id":"italian","name":"italiano","serviceId":"it"},{"id":"vietnamese","name":"Tiếng Việt","serviceId":"vi"},{"id":"korean","name":"한국어","serviceId":"ko"},{"id":"maltese","name":"Malti","serviceId":"mt"},{"id":"finnish","name":"suomi","serviceId":"fi"},{"id":"catalan","name":"català","serviceId":"ca"},{"id":"croatian","name":"hrvatski","serviceId":"hr"},{"id":"bosnian","name":"bosnian","serviceId":"bs-Latn"},{"id":"polish","name":"Polski","serviceId":"pl"},{"id":"latvian","name":"latviešu","serviceId":"lv"},{"id":"maori","name":"Maori","serviceId":"mi"}],
json:[{"id":"ukrainian","name":"УкраїнськаName","serviceId":"uk"},{"id":"norwegian","name":"Norge","serviceId":"no"},{"id":"welsh","name":"color name","serviceId":"cy"},{"id":"dutch","name":"nederlands","serviceId":"nl"},{"id":"japanese","name":"日本語","serviceId":"ja"},{"id":"filipino","name":"Pilipino","serviceId":"fil"},{"id":"english","name":"English","serviceId":"en"},{"id":"lao","name":"ກະຣຸນາ","serviceId":"lo"},{"id":"telugu","name":"తెలుగుQFontDatabase","serviceId":"te"},{"id":"romanian","name":"Română","serviceId":"ro"},{"id":"nepali","name":"नेपालीName","serviceId":"ne"},{"id":"french","name":"Français","serviceId":"fr"},{"id":"haitian_creole","name":"Kreyòl ayisyen","serviceId":"ht"},{"id":"czech","name":"český","serviceId":"cs"},{"id":"swedish","name":"Svenska","serviceId":"sv"},{"id":"russian","name":"Русский язык","serviceId":"ru"},{"id":"malagasy","name":"Malagasy","serviceId":"mg"},{"id":"burmese","name":"ဗာရမ်","serviceId":"my"},{"id":"pashto","name":"پښتوName","serviceId":"ps"},{"id":"thai","name":"คนไทย","serviceId":"th"},{"id":"armenian","name":"Արմենյան","serviceId":"hy"},{"id":"chinese_simplified","name":"简体中文","serviceId":"zh-CHS"},{"id":"persian","name":"Persian","serviceId":"fa"},{"id":"chinese_traditional","name":"繁體中文","serviceId":"zh-CHT"},{"id":"kurdish","name":"Kurdî","serviceId":"ku"},{"id":"turkish","name":"Türkçe","serviceId":"tr"},{"id":"hindi","name":"हिन्दी","serviceId":"hi"},{"id":"bulgarian","name":"български","serviceId":"bg"},{"id":"malay","name":"Malay","serviceId":"ms"},{"id":"swahili","name":"Kiswahili","serviceId":"sw"},{"id":"oriya","name":"ଓଡିଆ","serviceId":"or"},{"id":"icelandic","name":"ÍslandName","serviceId":"is"},{"id":"irish","name":"Íris","serviceId":"ga"},{"id":"khmer","name":"ខ្មែរKCharselect unicode block name","serviceId":"km"},{"id":"gujarati","name":"ગુજરાતી","serviceId":"gu"},{"id":"slovak","name":"Slovenská","serviceId":"sk"},{"id":"kannada","name":"ಕನ್ನಡ್Name","serviceId":"kn"},{"id":"hebrew","name":"היברית","serviceId":"he"},{"id":"hungarian","name":"magyar","serviceId":"hu"},{"id":"marathi","name":"मराठीName","serviceId":"mr"},{"id":"tamil","name":"தாமில்","serviceId":"ta"},{"id":"estonian","name":"eesti keel","serviceId":"et"},{"id":"malayalam","name":"മലമാലം","serviceId":"ml"},{"id":"inuktitut","name":"ᐃᓄᒃᑎᑐᑦ","serviceId":"iu"},{"id":"arabic","name":"بالعربية","serviceId":"ar"},{"id":"deutsch","name":"Deutsch","serviceId":"de"},{"id":"slovene","name":"slovenščina","serviceId":"sl"},{"id":"bengali","name":"বেঙ্গালী","serviceId":"bn"},{"id":"urdu","name":"اوردو","serviceId":"ur"},{"id":"azerbaijani","name":"azerbaijani","serviceId":"az"},{"id":"portuguese","name":"português","serviceId":"pt"},{"id":"samoan","name":"lifiava","serviceId":"sm"},{"id":"afrikaans","name":"afrikaans","serviceId":"af"},{"id":"tongan","name":"汤加语","serviceId":"to"},{"id":"greek","name":"ελληνικά","serviceId":"el"},{"id":"indonesian","name":"IndonesiaName","serviceId":"id"},{"id":"spanish","name":"Español","serviceId":"es"},{"id":"danish","name":"dansk","serviceId":"da"},{"id":"amharic","name":"amharic","serviceId":"am"},{"id":"punjabi","name":"ਪੰਜਾਬੀName","serviceId":"pa"},{"id":"albanian","name":"albanian","serviceId":"sq"},{"id":"lithuanian","name":"Lietuva","serviceId":"lt"},{"id":"italian","name":"italiano","serviceId":"it"},{"id":"vietnamese","name":"Tiếng Việt","serviceId":"vi"},{"id":"korean","name":"한국어","serviceId":"ko"},{"id":"maltese","name":"Malti","serviceId":"mt"},{"id":"finnish","name":"suomi","serviceId":"fi"},{"id":"catalan","name":"català","serviceId":"ca"},{"id":"croatian","name":"hrvatski","serviceId":"hr"},{"id":"bosnian","name":"bosnian","serviceId":"bs-Latn"},{"id":"polish","name":"Polski","serviceId":"pl"},{"id":"latvian","name":"latviešu","serviceId":"lv"},{"id":"maori","name":"Maori","serviceId":"mi"}],
/*
获取map形式的语言列表
key为 translate.service name
@ -4391,7 +4811,16 @@ var translate = {
send:function(url, data, func, method, isAsynchronize, headers, abnormalFunc, showErrorLog){
//post提交的参数
var params = '';
if(data != null){
if(data == null || typeof(data) == 'undefined'){
data = {};
}
//加入浏览器默认语种 v3.6.1 增加以便更好的进行自动切换语种
data.browserDefaultLanguage = translate.util.browserDefaultLanguage();
if(typeof(translate.enterprise.key) != 'undefined' && typeof(translate.enterprise.key) == 'string' && translate.enterprise.key.length > 0){
data.key = translate.enterprise.key;
}
if(typeof(data) == 'string'){
params = data; //payload 方式
}else{
@ -4403,9 +4832,6 @@ var translate = {
params = params + index + '=' + data[index];
}
}
}
if(url.indexOf('https://') == 0 || url.indexOf('http://') == 0){
//采用的url绝对路径
@ -4468,7 +4894,7 @@ var translate = {
//判断是否是v2版本的翻译如果是 translate.service 模式并且没有使用企业级翻译参会提示
//2024.3月底开始翻译使用量增加的太快开源的翻译服务器有点扛不住经常出故障所以直接把这个提示加到这里
if(translate.service.name == 'translate.service' && !translate.enterprise.isUse){
console.log('----- translate.js 提示 -----\n检测到您正在使用v2的旧版本并且当前的v2接口恰好处于不稳定状态所以您当前的翻译是并没有生效也就是并没有正常进行翻译的不过这不是您的问题是v2版本的翻译通道因为开源免费使用的人太多导致的偶尔不稳定如果您想正常使用建议您进行一下操作\n建议一切换到v3最新版本的 client.edge 翻译模式设置方式可以参考 http://translate.zvo.cn/43086.html 它是2024年初新出的V3版本的翻译模式翻译效果更稳定而且也是完全免费使用\n建议二启用企业级稳定翻译有些网站对翻译稳定性实时性要求比较高的可以考虑采用这种方式. 使用方式可参考 http://translate.zvo.cn/43262.html 这种方式是 2024.3月底应不少用户建议推出的一个独立翻译通道这个翻译通道仅仅只有提供赞助的人才能使用使用人数少多台翻译服务器组件的自动负载以及健康检查耗时最短的最优翻译方案使翻译更稳定\n\n建议一跟建议二的区别是建议一延续了translate.js三年以来一直贯彻的开源免费的方针同时也提供了相对稳定的翻译支持它的翻译稳定性还是信得过的一般使用这种就行而建议二它对稳定性及翻译速度接口响应专门进行了深度优化它的唯一缺点就是花钱\n-------------');
console.log('----- translate.js 提示 -----\n非常抱歉translate.service 开源免费的翻译服务器当前并发及流量太大导致阻塞\n这个情况是时不时发生的大概一天24小时可能会有一二十分钟这种情况主要是因为使用量太大了月使用量能超四十亿次所以在高发时会出现这种情况\n解决这种情况可以有两种方案\n方案一使用采用最新版本 3.8.0及更高版本js引用文件为 https://cdn.staticfile.net/translate.js/3.8.0/translate.js 并且使用 client.edge 模式 增加一行设置代码就好可参考 https://translate.zvo.cn/4081.html 这样就不会再出现这种情况了这个是我们的 translate.service 通道阻塞导致更换别的通道就可以避免这样了而且这个方案也是完全免费的 \n方案二采用企业级稳定翻译通道 ,但是这个相比于 方案一 来说是有一定的收费的大概一年600这个就是专门为了高速及高稳定准备的而相比于这个方案二方案一则是全免费的 因为方案二我们是部署了两个集群而每个集群又下分了数个网络节点包含中国大陆香港美国欧洲 等多个州充分保障稳定高效同样也产生了不少成本所以才需要付费更多信息说明可以参考 http://translate.zvo.cn/4087.html \n\n-------------');
}
//console.log(xhr);
@ -4510,16 +4936,63 @@ var translate = {
//打印翻译结果
console.log(data);
});
*/
translateText:function(texts, func){
if(typeof(texts) == 'string'){
texts = [texts];
使用案例三
var obj = {
from:'chinese_simplified',
to:'english',
texts: ['我是翻译的第一句','我是翻译的第二句','我是翻译的第三句']
}
translate.request.translateText(obj, function(data){
//打印翻译结果
console.log(data);
});
*/
translateText:function(obj, func){
var texts = new Array();
var from = translate.language.getLocal();
var to = translate.language.getCurrent();
if(typeof(obj) == 'string'){
//案例一的场景传入单个字符串
texts[0] = [obj];
}else{
//不是字符串了而是对象了判断是案例二还是案例三
var type = Object.prototype.toString.call(obj);
//console.log(type);
if(type == '[object Array]'){
//案例二
texts = obj;
}else if(type == '[object Object]'){
//案例三
if(typeof(obj.texts) == 'undefined'){
console.log('translate.request.translateText 传入的值类型异常因为你没有传入 obj.texts 要翻译的具体文本 请查阅文档 https://translate.zvo.cn/4077.html');
}
if(typeof(obj.texts) == 'string'){
//单个字符串
texts = [obj.texts];
}else{
//多个字符串数组形态
texts = obj.texts;
}
if(typeof(obj.from) == 'string' && obj.from.length > 0){
from = obj.from;
}
if(typeof(obj.to) == 'string' && obj.to.length > 0){
to = obj.to;
}
}else{
console.log('translate.request.translateText 传入的值类型错误请查阅文档 https://translate.zvo.cn/4077.html');
return;
}
}
var url = translate.request.api.translate;
var data = {
from:translate.language.getLocal(),
to: translate.language.getCurrent(),
from:from,
to: to,
text:encodeURIComponent(JSON.stringify(texts))
};
//console.log(data);
@ -4919,7 +5392,13 @@ var translate = {
//主节点额外权重降低更追求响应速度
translate.request.speedDetectionControl.hostMasterNodeCutTime = 300;
translate.request.api.host=['https://beijing.enterprise.api.translate.zvo.cn/','https://deutsch.enterprise.api.translate.zvo.cn/', 'https://america.api.translate.zvo.cn:666/'];
translate.request.api.host=['https://america-enterprise-api-translate.zvo.cn/','https://beijing.enterprise.api.translate.zvo.cn/','https://deutsch.enterprise.api.translate.zvo.cn/', 'https://america.api.translate.zvo.cn:666/', 'https://api.translate.zvo.cn:666/', 'https://api.translate.zvo.cn:888/'];
if(translate.service.name == 'client.edge'){
translate.service.name = 'translate.service';
console.log('您已启用了企业级翻译通道 translate.enterprise.use(); (文档https://translate.zvo.cn/4087.html) , 所以您设置的 translate.service.use(\'client.edge\'); (文档https://translate.zvo.cn/4081.html) 将失效不起作用有企业级翻译通道全部接管');
return;
}
},
/*
自动适配翻译服务通道如果当前所有网络节点均不可用会自动切换到 edge.client 进行使用
@ -4937,8 +5416,22 @@ var translate = {
translate.service.name = 'client.edge';
}
}
}
},
/* 企业级翻译通道的key v3.12.3.20250107 增加针对打包成APP的场景 */
key:'',
},
/*
如果使用的是 translate.service 翻译通道那么翻译后的语种会自动以小写的方式进行显示
如果你不想将翻译后的文本全部以小写显示而是首字母大写那么可以通过此方法设置一下
v3.8.0.20240828 增加
目前感觉应该用不到所以先忽略
*/
/*
notConvertLowerCase:function(){
},
*/
/*
初始化如版本检测初始数据加载等 v2.11.11.20240124 增加
@ -5006,8 +5499,16 @@ var nodeuuid = {
//console.log(Array.prototype.indexOf.call(childs, node));
}else{
// 使用querySelectorAll()方法获取所有与node元素相同标签名的子节点
childs = parent.querySelectorAll(node.tagName);
// 使用indexOf()方法获取node元素在子节点集合中的位置
//childs = parent.querySelectorAll(node.tagName);
// 不使用querySelectorAll手动遍历子节点来找到相同标签名的子节点
childs = [];
var allChilds = parent.childNodes;
for (var i = 0; i < allChilds.length; i++) {
if (allChilds[i].tagName === node.tagName) {
childs.push(allChilds[i]);
}
}
}
var index = Array.prototype.indexOf.call(childs, node);
//console.log('--------'+node.tagName);
@ -5033,3 +5534,19 @@ var nodeuuid = {
}
console.log('------ translate.js ------\nTwo lines of js html automatic translation, page without change, no language configuration file, no API Key, SEO friendly! Open warehouse : https://github.com/xnx3/translate \n两行js实现html全自动翻译 无需改动页面无语言配置文件无API Key对SEO友好完全开源代码仓库https://gitee.com/mail_osc/translate');
/**
* 兼容 AMDCMDCommonJS 规范
* node 环境使用`npm i i18n-jsautotranslate` 安装包
*/
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define([], () => factory());
} else if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else {
root['translate'] = factory();
}
})(this, function () {
return translate;
});