# 重构要点

重构前需要确认是否需要如下功能,引入对应组件

  • 多语言翻译
  • cookie 管理组件
  • 通用页脚组件

提示

海外 ihub 不支持路径分离,没有 ossweb-img 文件夹,图片和静态资源文件就放到同级目录,例如 images font

禁止引用国内常用 JS 库,转为使用海外域名的 JS 库,详情查看 常用 JS 库

项目目录可以为如下

  a20241014subscribe
  ├─ images
    ├─ bg.jpg
    ├─ hreo.mp3
    └─ ...
  ├─ font
    ├─ MarkPro-Bold.ttf
    └─ ...
  ├─ css
    ├─ index.css
    └─ ...
  ├─ js
    ├─ index.js
    └─ lang.js
  └─ index.html

重点

无分享需求的页面,可直接使用以下通用模板,一个 html 实现多语言
有分享需求的页面请看 多语言区分html

# 通用模板

引入了四种组件:上报组件(必须)、翻译组件、cookie 管理组件、页脚组件,根据项目需要进行取舍

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta name="keywords" content="Auto chess,LOL,LOLM,League of Legends,Hero,Tactical,Arena of Valor,MLBB,Mobile Legend: BangBang,Dota">
  <meta name="description" content="Golden Spatula is a champion auto-battler strategy mobile game. It is one of the ‘TFT franchise’ titles together with Teamfight Tactics and Teamfight Tactics Mobile from Riot Games, and is a mobile-exclusive game built primarily with the mobile audience in mind.In Golden Spatula, players need to fully utilize their intellect to recruit champions from a random pool and form the best lineup. They can empower their lineup by leveling up their champions, gearing them with various items including the powerful golden spatula itself. In each match, eight players use their battle formations to engage in one-on-one combat, continuously eliminating each other until the final victorious player remains.">
  
  <!-- 通用分享图 -->
  <meta itemprop="image" content="https://goldenspatula.com/resources/share.jpg">
  <!-- facebook 分享 -->
  <meta property="og:type" content="website">
  <meta property="og:site_name" content="goldenspatula.com">
  <meta property="og:title" content="Golden Spatula">
  <meta property="og:description" content="Golden Spatula is a champion auto-battler strategy mobile game. It is one of the ‘TFT franchise’ titles together with Teamfight Tactics and Teamfight Tactics Mobile from Riot Games, and is a mobile-exclusive game built primarily with the mobile audience in mind.In Golden Spatula, players need to fully utilize their intellect to recruit champions from a random pool and form the best lineup. They can empower their lineup by leveling up their champions, gearing them with various items including the powerful golden spatula itself. In each match, eight players use their battle formations to engage in one-on-one combat, continuously eliminating each other until the final victorious player remains.">
  <meta property="og:url" content="https://goldenspatula.com">
  <meta property="og:image" content="https://goldenspatula.com/resources/share.jpg">
  <!-- twitter 分享 -->
  <meta name="twitter:site" content="@goldenspatula">
  <meta name="twitter:title" content="Golden Spatula">
  <meta name="twitter:description" content="Golden Spatula is a champion auto-battler strategy mobile game. It is one of the ‘TFT franchise’ titles together with Teamfight Tactics and Teamfight Tactics Mobile from Riot Games, and is a mobile-exclusive game built primarily with the mobile audience in mind.In Golden Spatula, players need to fully utilize their intellect to recruit champions from a random pool and form the best lineup. They can empower their lineup by leveling up their champions, gearing them with various items including the powerful golden spatula itself. In each match, eight players use their battle formations to engage in one-on-one combat, continuously eliminating each other until the final victorious player remains.">
  <meta name="twitter:url" content="https://goldenspatula.com">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:image" content="https://goldenspatula.com/resources/share.jpg">
  <meta name="twitter:image:src" content="https://goldenspatula.com/resources/share.jpg">

  <title data-t="title"></title>
</head>
<body>
  <!-- 上报测试 -->
  <a href="javascript:void(0);" onclick="JKsendReportData('中文信息', 'English')">测试上报</a>
  <!-- 翻译测试 在标签中用 data-t 属性承载翻译的 key -->
  <h1 data-t="title"></h1>
  <p data-t="description"></p>
  <div><span data-t="Please choose a login method."></span></div>
  <!-- 页脚容器 -->
  <div id="footer-container"></div>

  <!-- 页脚组件引入 -->
  <script src="https://goldenspatula.com/plugins/footer/index.js"></script>
  <!-- 翻译组件引入 -->
  <script src="https://goldenspatula.com/plugins/i18next/i18next.min.js"></script>
  <!-- 上报组件引入 -->
  <script src="https://goldenspatula.com/plugins/report/index.js"></script>
  <!-- cookie 管理插件引入,必须加上 type="module" 标识模块化加载此脚本 -->
  <script type="module">
    import('https://goldenspatula.com/plugins/cookie/index.min.js').then(() => {
      let OReport = null
      // 初始化 cookie 管理组件
      new OverseasCookieConsent((flag) => {
        console.log('cookie偏好分析:', flag)
        // 控制是否上报
        JKReportConfig.open = flag
        // 数据上报一定要放在 cookie 组件初始化之后
        if (!OReport && flag) {
          // 如果还没初始化上报 且 允许上报,则执行一次初始化
          OReport = new OverseasReport({
            id: 'a20241011testplugin', // 项目名称
            channel: queryParams.get('media_channel') // 渠道,如需统计不同渠道的数据,通过 url 参数 media_channel 来区分
          })
        }
      })
    })
  </script>
  <!-- 导入当前项目的语言翻译文件 -->
  <script src="./js/lang.js"></script>
  <script>
    // 读取 url 参数
    const queryParams = new URLSearchParams(location.search)
    // 获取浏览器默认语言
    const browserLang = (navigator.language || navigator.userLanguage).split('-')[0]
    // 临时语言
    const tempCurLang = queryParams.get('lang') || browserLang
    // 所有语言
    const LANG_LIST = ['en', 'zh', 'th']
    // 判断当前语言,优先级:url lang 参数 -> 浏览器语言 -> 默认语言 en
    const currentLang = LANG_LIST.includes(tempCurLang) ? tempCurLang : LANG_LIST[0]
    // 设置 html 的语言,cookie 组件会读取 document lang 属性显示对应语言
    document.documentElement.lang = currentLang

    // 初始化翻译工具
    i18next.init({
      lng: currentLang, // 当前语言
      fallbackLng: "en", // 回退语言
      resources: langResources, // 翻译文件
    }, (err) => {
      if (err) return console.error(err);
      // 执行 html 中的翻译
      document.querySelectorAll("[data-t]").forEach((element) => {
        const key = element.getAttribute("data-t");
        element.textContent = i18next.t(key);
      });
    });

    // 定义翻译方法 $t
    const $t = (key) => i18next.t(key);

    // 初始化页脚,传入当前语言
    new FooterComponent('footer-container', currentLang);

    console.log('测试脚本的翻译 $t:', $t("description"));
  </script>
</body>
</html>

# 翻译文件

其中 ./js/lang.js 翻译文件的格式如下

// 定义翻译内容
const langResources = {
  en: {
    translation: {
      title: "Golden Spatula",
      description: "description",
      "Please choose a login method.": "Please choose a login method.",
    },
  },
  th: {
    translation: {
      title: "Golden Spatula",
      description: "คำอธิบาย",
      "Please choose a login method.": "กรุณาเลือกวิธีล็อกอิน",
    },
  },
  zh: {
    translation: {
      title: "Golden Spatula",
      description: "描述",
      "Please choose a login method.": "请选择一种登录方式",
    },
  },
};

提示

翻译语言和文案找产品提供

# 语言样式

每种语言字体通常都不一样,为了防止页面加载时出现字体渲染不及时的问题,字体文件可做预加载处理

<link rel="preload" href="../font/AktivGroteskCd_Blk.ttf" as="font" type="font/woff2" crossorigin="anonymous">

如果要单独控制某种语言的 css 样式,可以在样式选择器前面加上 html lang 属性控制

html[lang="zh"] .class-name { }

html[lang="en"] .class-name { }

html[lang="th"] .class-name { }