进行翻译的生命周期监控及触发

当用户点击切换语言时触发

执行 translate.changeLanguage('english'); 时,进行触发。
以下几个动作会触发此:

  1. 直接执行这个 translate.changeLanguage('english'); 方法
  2. 点击自带的 select 中的某个语言切换时,它实际触发的也是translate.changeLanguage('english');

执行 translate.changeLanguage('english'); 时,会进行:

  1. 相关初始化
  2. 触发 translate.reset() 还原,将翻译后的文本还原回翻译之前的原本的文字以便继续进行翻译
  3. 重新绘制 select 选择语言
  4. 触发translate.execute()翻译执行以及触发子iframe以及父级iframe跟随(子跟父iframe中也触发 translate.changeLanguage(…))一起切换语言

执行前触发

在触发 translate.changeLanguage('english'); 进行切换语种时,在执行这个切换时,立即触发,执行自己在这里设置的方法,执行完毕后,再去执行 translate.changeLanguage('english'); 它里面的具体切换逻辑。
设置方式:

  1. translate.lifecycle.changeLanguage.trigger.push(function(data){
  2. console.log('当前切换为:'+data.to);
  3. });

data 参数:

  • to 翻译为的语种,如 english

实际执行时,会先看到控制台输出这个日志,然后页面再进行的语种切换。

已还原且还未进行翻译时触发

在触发 translate.reset() 之后、重新绘制 select 选择语言及执行切换之前,触发。

  1. translate.lifecycle.changeLanguage.resetAfter.push(function(data){
  2. console.log('当前切换为:'+data.to);
  3. });

data 参数:

  • to 翻译为的语种,如 english

当执行翻译时触发

当执行 translate.execute(); 之后,它会进行一下操作:

  1. 进行一些初始化及检测,如果不达标则直接终止不做任何处理,同时也不会触发任何下面的事件。
  2. 进行图片翻译
  3. 对要翻译的区域的所有节点进行扫描,识别出需要进行翻译的文本,进行收集分析,加入待翻译的文本队列
  4. 对待翻译的文本队列中的翻译文本进行本地浏览器缓存命中处理,如果本地缓存全部命中了,那也就没有后面的网络请求什么事了
  5. 对本地浏览器缓存命中之后,没有被缓存命中,未进行翻译的文本,进行通过请求网络接口的方式进行翻译处理,发起网络请求,将要翻译的文本发送到翻译服务进行翻译,等待拿到翻译结果后,进行翻译。(这个会产生 50ms ~ 10s 的时间差,也是造成视觉上翻译速度快慢的最根本原因)
  6. 完毕

以下提供的几个针对其生命周期中的某个特定点,提供监控及主动触发你自定义的方法,来做一些事情。

翻译触发

每当触发执行 translate.execute() 时,会立即触发此。
这个触发是指在所有判断之前,也就是只要 触发了 translate.execute() 会立即触发此,然后在进行执行其他的。
设置方式:

  1. translate.lifecycle.execute.trigger.push(function(data){
  2. console.log(data.uuid);
  3. });
  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识
  • to 翻译为的语种,如 japanese
  • docs 参与翻译的元素节点数组。
    当前触发 translate.execute() 要进行翻译的元素。
    比如单纯触发执行 translate.execute() 、translate.request.listener.start() 那么这里 docs 则是 通过 translate.setDocuments(…) 所设置的元素。 如果没有使用 translate.setDocuments(…) 设置过,那就是翻译整个html页面。
    如果是 translate.listener.start(); 监控页面发生变化的元素进行翻译,则这里的docs 则是发生变化的元素
  • executeTriggerNumber 整数型,当前触发 translate.execute() 执行,属于打开页面后第几次执行 translate.execute() , 它不会经过任何初始化判断,只要触发了 translate.execute() 就会立即+1,即使初始化判断当前不需要翻译、或者当前正在翻译需要排队等待,它依旧也会+1
  • 返回值 它有返回参数,boolean 类型:
    • true 则是继续执行 translate.execute()
    • false 则是不继续执行,直接终止本次的 translate.execute() 也就是后面的 translate.lifecycle.execute.start 都不会执行到,不会触发。
    • 如果钩子没有任何返回值,则默认是 true
    • 如果本钩子有多个实现,其中某个实现返回 false,它不会阻止 translate.lifecycle.execute.trigger 的其他钩子执行,其他的 translate.lifecycle.execute.trigger 钩子实现也都会触发执行。 只不过里面只要其中有一个是返回 false,那么 translate.execute() 都会终止,并且终止后也会触发 translate.lifecycle.execute.finally 执行结束的钩子。
    • 示例: 比如,如果发现目标语种是英语,则终止翻译:
      1. translate.lifecycle.execute.trigger.push(function(data){
      2. if(data.to === 'english'){
      3. return false;
      4. }
      5. });

扩展用法 - 当用户打开页面后,第一次触发 translate.execute() 时,进行触发

  1. translate.lifecycle.execute.trigger.push(function(data){
  2. if(translate.executeTriggerNumber === 1){
  3. console.log('这是打开页面后,第一次触发 translate.execute() ,因为translate.executeTriggerNumber 记录的是translate.execute() 触发的次数。');
  4. }
  5. });

翻译开始

每当触发执行 translate.execute() 时,会先进行当前是否可以正常进行翻译的判定,比如 当前语种是否就已经是翻译之后的语种了是否没必要翻译了等。(这些初始判定可以理解成它的耗时小于1毫秒,几乎没有耗时)
经过初始的判断后,发现允许被翻译,那么在向后执行之前,先触发此。
也就是在进行翻译之前,触发此。
设置方式:

  1. translate.lifecycle.execute.start.push(function(data){
  2. console.log(data.uuid);
  3. });
  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识
  • to 翻译为的语种,如 japanese

发起网络请求前

每当触发执行翻译动作 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求前,触发此

  1. translate.lifecycle.execute.translateNetworkBefore.push(function(data){
  2. console.log(data.uuid);
  3. });
  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识
  • from 来源语种,翻译前的语种,如 english
  • to 翻译为的语种,如 japanese
  • texts 要翻译的文本,它是一个数组形态,是要进行通过API翻译接口进行翻译的文本,格式如 ['你好','世界']
  • nodes 要翻译的文本的node集合,也就是有哪些node中的文本参与了 通过API接口进行翻译文本,这里是这些node。 格式如 [node1, node2, …]

发起网络请求后

每当触发执行翻译动作 translate.execute() 时,当缓存中未发现,需要请求翻译API进行翻译时,在发送API请求后,也就是拿到 API响应、或网络请求失败后,立即触发此

  1. translate.lifecycle.execute.translateNetworkAfter.push(function(data){
  2. console.log(data.uuid);
  3. });
  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识
  • from 来源语种,翻译前的语种,如 english
  • to 翻译为的语种,如 japanese
  • texts 要翻译的文本,它是一个数组形态,是要进行通过API翻译接口进行翻译的文本,格式如 ['你好','世界']
  • nodes 要翻译的文本的node集合,也就是有哪些node中的文本参与了 通过API接口进行翻译文本,这里是这些node。 格式如 [node1, node2, …]
  • result 本次网络请求的结果, 1成功, 0失败。 网络不通,翻译结果失败(translate.json返回result非1)都是记入0
  • info 如果result为0,这里是失败信息

说明

  1. 不管网络请求是否成功,它都会被触发
  2. 不管翻译结果是否成功,它都会被触发
  3. 在网络请求完毕后立即触发,不会再有其他时间损耗。也就是它是在网络请求完毕后,渲染UI页之前就会被触发。

翻译完成

translate.execute() 的翻译渲染完毕触发。
这个完毕是指它当触发 translate.execute() 进行翻译后,无论是全部命中了本地缓存,还是有部分要通过翻译接口发起多个网络请求,当拿到结果(缓存中的翻译结果或多个不同的有xx语种翻译的网络请求全部完成,这个完成是包含所有成功跟失败的响应),并完成将翻译结果渲染到页面中进行显示后,触发此
它跟 translateNetworkFinish 的区别是, translateNetworkFinish 仅仅针对有网络请求的才会触发,而 renderFinish 是无论何种情况,只要 translate.execute() 执行完毕都会触发。比如全部命中了浏览器本地缓存,无需发起任何网络翻译请求这种情况时,也会触发。

  1. translate.lifecycle.execute.renderFinish.push(function(uuid, to){
  2. });
  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识
  • to 翻译为的语种,如 japanese

实际使用场景示例:
比如,我有一个中文网站,翻译为英文浏览时,要做到完全不显示中文的文字内容,不出现先显示中文然后瞬间在显示英文的情况。
操作方式:
首先,在原本中文网站加载后,先用CSS显示一个遮罩层,将原本显示中文的部分遮罩起来,在遮罩层上,用英文显示一个提示信息,比如 <div id="load">loading...</div>
然后在 translate.execute(); 的前面,增加一个翻译完成的监控,以便在翻译完成后,来触发将 loading… 给隐藏掉 :

  1. translate.lifecycle.execute.renderFinish.push(function(uuid, to){
  2. document.getElementById('load').style.display='none';
  3. });

这样就实现了打开网页后,先在页面的中文上面出现个英文提示 loading… 给用户一个友好的提示,当翻译执行完毕后(页面的中文已经改成了英文)将 <div id="load"> 这个id元素隐藏,将loading… 的提示隐藏,将英文的页面显示出来。
其实这个示例就仅仅只是一个示例,你如果想要达到完全不显示源语言文字的效果,可以参考 网页打开时自动隐藏文字,翻译完成后显示译文 这里有现成的功能可以直接拿来达到这个效果。

执行结束

每当 translate.execute() 执行结束、中止、自检不通过跳出 … 等,都会触发这个。
注意,不管在 translate.execute() 是否自检通过、不管是否进行了翻译、不管文本翻译API接口是否拿到翻译结果,只要 translate.execute 执行完毕或触发了什么自检不通过不再往下执行,都会触发这个。
这个仅仅只是用于 translate.execute() 从上而下执行完跳出时,进行触发的。

  1. translate.lifecycle.execute.finally.push(function(data){
  2. console.log(data.uuid);
  3. });

data 参数:

  • uuid translate.nodeQueue[uuid] 这里的唯一标识,每次执行 translate.execute() 时都会创建一个针对此的uuid唯一标识。如果当前没有进行正常翻译,比如自检失败不在执行跳出了,那这个将会返回空字符串 ‘’
  • to 翻译为的语种,如 japanese。 如果当前没有进行正常翻译,比如自检失败不在执行跳出了,那这个将会返回空字符串 ‘’
  • state 是何种状态执行结束的。整数型,取值有:
    • 2 自定义的translate.lifecycle.execute.trigger钩子返回了false,终止继续执行时触发的
    • 4 当前翻译未完结,新翻译任务已加入等待翻译队列,待上个翻译任务结束后便会执行当前翻译任务
    • 6 没有指定翻译目标语言,不翻译
    • 8 本地语种跟要翻译的目标语种一样,且没有启用本地语种也强制翻译,那么当前不需要执行翻译,退出
    • 16 已经匹配完自定义术语跟离线翻译,但是用户设置了不掉翻译接口进行翻译,不在向后执行通过文本翻译接口进行翻译
    • 18 已经匹配完自定义术语跟离线翻译,此时所有要翻译的文本都已经匹配完了,没有在需要通过文本翻译接口进行翻译的了
    • 21 进行通过文本翻译API进行调用接口翻译时,某个语种的数据校验失败导致退出。 这个情况理论上应该不会出现,预留这个情况,后续将会剔除这个状态
    • 25 已通过文本翻译接口发起所有翻译请求,translate.execute 执行完毕。 (只是发起网络请求,不代表翻译完成,因为这里还没有等着拿到网络请求的响应结果,还处于网络请求的过程中)
  • triggerNumber translate.execute() 方法已经被触发过多少次了, 只要 translate.execute() 被触发,它就会在触发时立即 +1 (translate.execute() 默认是同一时刻只能执行一次,这个触发是在这个同一时刻执行一次的判定之前进行++ 的,如果这个同一时刻执行一次不通过,还有其他在执行,进入排队执行时,这里也会++ ,当从排队的中顺序排到进行执行时,又会执行++ ) 。 当页面打开第一次触发执行translate.execute(),这里便是 1

注意 它触发的可能会非常多,比如如果你启用了 translate.listener.start();translate.request.listener.start(); … 等,都会自动触发此 translate.execute()

注意

  1. 需要 translate.js v3.18.93.20251110 及更高版本
  2. 需要设置在 translate.execute() 前面
  3. 这里的监听仅仅针对网页正常翻译,也就是 translate.execute()translate.changeLanguage(...) 、以及设置动态监控网页变化、动态监控网络请求后触发的翻译,会触发这里。
    但是像是扩展使用如 translate.request.translateText(…) 手动调用翻译接口执行翻译操作 这个是会对他生效的,它不会触发以上的监听。