wangzhibo
2026-07-16 005761a4fa0e5b03f5af869274bc85f8bab347d6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
const I18n = {
  currentLang: 'zh',
  strings: {},
  languages: [
    { code: 'zh', labelKey: 'lang.zh', locale: 'zh-CN', file: 'config/i18n/zh.json' },
    { code: 'en', labelKey: 'lang.en', locale: 'en-US', file: 'config/i18n/en.json' },
    { code: 'ko', labelKey: 'lang.ko', locale: 'ko-KR', file: 'config/i18n/ko.json' },
    { code: 'ja', labelKey: 'lang.ja', locale: 'ja-JP', file: 'config/i18n/ja.json' }
  ],
 
  async load(lang) {
    const langConfig = this.languages.find(l => l.code === lang);
    if (!langConfig) return;
    const res = await fetch(langConfig.file);
    this.strings = await res.json();
    this.currentLang = lang;
    document.documentElement.lang = langConfig.locale;
  },
 
  t(key) {
    return this.strings[key] || key;
  },
 
  getLocale() {
    const langConfig = this.languages.find(l => l.code === this.currentLang);
    return langConfig ? langConfig.locale : 'zh-CN';
  },
 
  applyToDOM() {
    document.querySelectorAll('[data-i18n]').forEach(el => {
      const key = el.getAttribute('data-i18n');
      el.textContent = this.t(key);
    });
    document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
      const key = el.getAttribute('data-i18n-placeholder');
      el.placeholder = this.t(key);
    });
    const titleEl = document.querySelector('title[data-i18n]');
    if (titleEl) {
      document.title = this.t(titleEl.getAttribute('data-i18n'));
    }
  },
 
  renderLangMenu(menuEl, onSelect) {
    menuEl.innerHTML = '';
    this.languages.forEach(lang => {
      const item = document.createElement('div');
      item.className = 'lang-menu-item' + (lang.code === this.currentLang ? ' active' : '');
      item.textContent = this.t(lang.labelKey);
      item.addEventListener('click', () => onSelect(lang.code));
      menuEl.appendChild(item);
    });
  }
};