我有一个NextJS应用程序,我想把谷歌自动翻译小部件添加到我的应用程序中。
所以做了一个这样的函数:
function googleTranslateElementInit() {
if (!window['google']) {
console.log('script added');
var script = document.createElement('SCRIPT');
script.src =
'//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit';
document.getElementsByTagName('HEAD')[0].appendChild(script);
}
setTimeout(() => {
console.log('translation loaded');
new window.google.translate.TranslateElement(
{
pageLanguage: 'tr',
includedLanguages: 'ar,en,es,jv,ko,pt,ru,zh-CN,tr',
//layout: google.translate.TranslateElement.InlineLayout.SIMPLE,
//autoDisplay: false,
},
'google_translate_element'
);
}, 500);
}
我在useEffect()
中调用这个函数,它会加载,但当我路由到另一个页面时,它会失效。当我检查控制台时,我看到了translation loaded
,所以每次都调用setTimeout
作用域,即使我路由到另一个页面,但翻译小部件没有出现,只有在刷新页面时才会出现。
我该如何解决这个问题?
感谢SILENT的回答:谷歌不再支持这个小部件。
因此,我将为NextJS配置next-i18next,它是一个i18n(具有动态json存储的轻量级翻译模块(。
此外,我认为这个小部件的问题是谷歌的JS代码将该小部件附加到DOM本身,因此它不附加到VirtualDOM,这就是为什么当我在应用程序中路由时,React检查了VirtualDOM并更新了DOM本身,这样小部件就消失了,因为它不在VirtualDOM上。(这只是猜测(
编辑:经过进一步测试,我发现此代码可能仍然不稳定。在生产中使用时要小心。
在自定义应用程序中使用以下代码,不要忘记将<div id="google_translate_element" />
放入页面或组件中。基于此和此答案。
import { useEffect } from 'react'
import { useRouter } from 'next/router'
const MyApp = ({ Component, pageProps }) => {
const { isFallback, events } = useRouter()
const googleTranslateElementInit = () => {
new window.google.translate.TranslateElement({ pageLanguage: 'en' }, 'google_translate_element')
}
useEffect(() => {
const id = 'google-translate-script'
const addScript = () => {
const s = document.createElement('script')
s.setAttribute('src', '//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit')
s.setAttribute('id', id)
const q = document.getElementById(id)
if (!q) {
document.body.appendChild(s)
window.googleTranslateElementInit = googleTranslateElementInit
}
}
const removeScript = () => {
const q = document.getElementById(id)
if (q) q.remove()
const w = document.getElementById('google_translate_element')
if (w) w.innerHTML = ''
}
isFallback || addScript()
events.on('routeChangeStart', removeScript)
events.on('routeChangeComplete', addScript)
return () => {
events.off('routeChangeStart', removeScript)
events.off('routeChangeComplete', addScript)
}
}, [])
return <Component {...pageProps} />
}
export default MyApp