在 vue (nuxt) 中动态更改 facebook sdk lang 代码
change facebook sdk lang code dynamically in vue (nuxt)
我目前正在 nuxt 中进行类似的简单实现。当我使用 1i8n 更改语言时,我想相应地更改 facebook sdk 语言,因此当我更改整个应用程序语言时,按钮会以给定的语言代码呈现。我的代码如下所示:
import config from '@/config'
export default {
data() {
return {
FB_APP_ID: config.appname.FB_APP_ID
}
},
mounted() {
var langua;
if (this.$i18n.locale == 'en') {
langua = "en_US";
}
if (this.$i18n.locale == 'de') {
langua = "de_DE";
}
window.fbAsyncInit = () => {
FB.init({
appId: this.FB_APP_ID,
cookie: true,
xfbml: true,
version: 'v2.8'
})
}
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/" + langua + "/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
}
它有效,但没有发生动态变化,我是否错过了按钮 sdk 上的异步之类的东西???不知道,我是 vue 的新手,非常感谢帮助。
我用this.$router.go(0);
点击语言切换的按钮解决了,我希望用另一种方式,但仍然找不到,反正现在页面重新加载时语言会改变以及 sdk 的 lang 代码,如果其他使用适当的语言。也许有一天我会找到更优雅的解决方案
That won’t work, the SDK can only be embedded and initialized once.
这不完全正确:有一个解决方法。
如果在头部添加新的脚本,加载一次就会执行。对于任何脚本都是如此。如果没有,则意味着该脚本有一个保护措施,可以通过检查其变量之一是否已定义来再次阻止 运行 相同的代码。
对于 Facebook SDK,它将检查 FB
是否已在全局定义,因此您只需在添加具有不同语言环境的新 sdk 脚本之前将其删除。
我的代码看起来有点不同,但我也在使用 Nuxt:
<template>
<div
:key="`fb-chat-${$i18n.locale}`"
class="fb-customerchat"
:page_id="pageId"
theme_color="#4586ff"
greeting_dialog_display="hide"
:logged_in_greeting="$t('greeting')"
:logged_out_greeting="$t('greeting')"
></div>
</template>
<script>
export default {
name: 'FacebookChat',
data() {
return {
pageId: process.env.FACEBOOK_PAGE_ID,
}
},
watch: {
'$i18n.locale': 'resetFacebookSdk',
},
mounted() {
this.initFacebookSdk()
},
methods: {
initFacebookSdk() {
if (!process.browser) return
const locale = this.$i18n.locale === 'de' ? 'de_DE' : 'en_US'
delete window.FB // needs to be undefined when inserting a second script with different locale
window.fbAsyncInit = function () {
window.FB.init({
appId: process.env.FACEBOOK_APP_ID,
autoLogAppEvents: true,
xfbml: true,
version: 'v10.0',
})
}
;(function (d, s, id) {
let js = d.getElementById(id),
fjs = d.getElementsByTagName(s)[0]
if (js) js.parentNode.removeChild(js) // remove script tag if exists
js = d.createElement(s)
js.id = id
js.src = `https://connect.facebook.net/${locale}/sdk/xfbml.customerchat.js`
fjs.parentNode.insertBefore(js, fjs)
})(document, 'script', `facebook-jssdk-${this.$i18n.locale}`)
},
resetFacebookSdk() {
const fbRoot = this.$el.closest('#fb-root')
if (!fbRoot) return
// Move fb-customerchat element outside of fb-root (created by Facebook SDK)
fbRoot.parentNode.insertBefore(this.$el, fbRoot)
// Delete fb-root to let Facebook SDK create it again
fbRoot.parentNode.removeChild(fbRoot)
this.initFacebookSdk()
},
},
}
</script>
您应该注意的事项:
- 语言环境是我元素的
key
属性的一部分,以使其在语言环境更改时重新呈现,以删除 sdk 添加的内容(属性、子元素)
- 有一个观察者在区域设置更改时调用
resetFacebookSdk
- 我修改了 sdk 代码片段以删除脚本标签(如果它已经存在)而不是什么都不做。这样我们就可以重新创建了。
- 元素
.fb-customerchat
已使用 key
属性清除,但 sdk 已使用新元素 #fb-root
对其进行包装。方法 resetFacebookSdk
负责将 .fb-customerchat
移出包装器并将其删除。
您可以在 our website 上看到它的实际效果(您可以在页脚中切换语言)。
希望对您有所帮助。如果有什么不清楚的地方,请告诉我。
我目前正在 nuxt 中进行类似的简单实现。当我使用 1i8n 更改语言时,我想相应地更改 facebook sdk 语言,因此当我更改整个应用程序语言时,按钮会以给定的语言代码呈现。我的代码如下所示:
import config from '@/config'
export default {
data() {
return {
FB_APP_ID: config.appname.FB_APP_ID
}
},
mounted() {
var langua;
if (this.$i18n.locale == 'en') {
langua = "en_US";
}
if (this.$i18n.locale == 'de') {
langua = "de_DE";
}
window.fbAsyncInit = () => {
FB.init({
appId: this.FB_APP_ID,
cookie: true,
xfbml: true,
version: 'v2.8'
})
}
(function(d, s, id){
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/" + langua + "/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
}
它有效,但没有发生动态变化,我是否错过了按钮 sdk 上的异步之类的东西???不知道,我是 vue 的新手,非常感谢帮助。
我用this.$router.go(0);
点击语言切换的按钮解决了,我希望用另一种方式,但仍然找不到,反正现在页面重新加载时语言会改变以及 sdk 的 lang 代码,如果其他使用适当的语言。也许有一天我会找到更优雅的解决方案
That won’t work, the SDK can only be embedded and initialized once.
这不完全正确:有一个解决方法。
如果在头部添加新的脚本,加载一次就会执行。对于任何脚本都是如此。如果没有,则意味着该脚本有一个保护措施,可以通过检查其变量之一是否已定义来再次阻止 运行 相同的代码。
对于 Facebook SDK,它将检查 FB
是否已在全局定义,因此您只需在添加具有不同语言环境的新 sdk 脚本之前将其删除。
我的代码看起来有点不同,但我也在使用 Nuxt:
<template>
<div
:key="`fb-chat-${$i18n.locale}`"
class="fb-customerchat"
:page_id="pageId"
theme_color="#4586ff"
greeting_dialog_display="hide"
:logged_in_greeting="$t('greeting')"
:logged_out_greeting="$t('greeting')"
></div>
</template>
<script>
export default {
name: 'FacebookChat',
data() {
return {
pageId: process.env.FACEBOOK_PAGE_ID,
}
},
watch: {
'$i18n.locale': 'resetFacebookSdk',
},
mounted() {
this.initFacebookSdk()
},
methods: {
initFacebookSdk() {
if (!process.browser) return
const locale = this.$i18n.locale === 'de' ? 'de_DE' : 'en_US'
delete window.FB // needs to be undefined when inserting a second script with different locale
window.fbAsyncInit = function () {
window.FB.init({
appId: process.env.FACEBOOK_APP_ID,
autoLogAppEvents: true,
xfbml: true,
version: 'v10.0',
})
}
;(function (d, s, id) {
let js = d.getElementById(id),
fjs = d.getElementsByTagName(s)[0]
if (js) js.parentNode.removeChild(js) // remove script tag if exists
js = d.createElement(s)
js.id = id
js.src = `https://connect.facebook.net/${locale}/sdk/xfbml.customerchat.js`
fjs.parentNode.insertBefore(js, fjs)
})(document, 'script', `facebook-jssdk-${this.$i18n.locale}`)
},
resetFacebookSdk() {
const fbRoot = this.$el.closest('#fb-root')
if (!fbRoot) return
// Move fb-customerchat element outside of fb-root (created by Facebook SDK)
fbRoot.parentNode.insertBefore(this.$el, fbRoot)
// Delete fb-root to let Facebook SDK create it again
fbRoot.parentNode.removeChild(fbRoot)
this.initFacebookSdk()
},
},
}
</script>
您应该注意的事项:
- 语言环境是我元素的
key
属性的一部分,以使其在语言环境更改时重新呈现,以删除 sdk 添加的内容(属性、子元素) - 有一个观察者在区域设置更改时调用
resetFacebookSdk
- 我修改了 sdk 代码片段以删除脚本标签(如果它已经存在)而不是什么都不做。这样我们就可以重新创建了。
- 元素
.fb-customerchat
已使用key
属性清除,但 sdk 已使用新元素#fb-root
对其进行包装。方法resetFacebookSdk
负责将.fb-customerchat
移出包装器并将其删除。
您可以在 our website 上看到它的实际效果(您可以在页脚中切换语言)。
希望对您有所帮助。如果有什么不清楚的地方,请告诉我。