You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript实现多语言网站:语言存储与选中状态显示问题

多语言网站语言选择持久化与头部展示实现问题

我是编程新手,正在尝试搭建多语言网站,目前已找到如下可正常运行的JS实现方案:

现有JS代码

let langs = document.querySelector(".langs"),
     link = document.querySelectorAll("a"),
     lgmenu = document.querySelector(".lgmenu");
     lglanguage = document.querySelector(".lglanguage");

link.forEach(el=>{
     el.addEventListener("click", ()=>{
          langs.querySelector(".active").classList.remove("active");
          el.classList.add("active");

          let attr = el.getAttribute("language")

          lgmenu.textContent = data[attr].lgmenu
          lglanguage.textContent = data[attr].lglanguage

     })

})

let data = {
     romanian: {
          lgmenu: "Meniu",
          lglanguage: "Alege limba"
     },
     english: {
          lgmenu: "Menu",
          lglanguage: "Choose language"
     }
}


window.localStorage.setItem("langs", "romanian");
window.localStorage.setItem("langs", "english");
window.localStorage.getItem('langs');

待解决问题

  1. 如何正确保存用户的语言选择,实现页面刷新、跨页面导航时语言配置不会重置?我已知晓可通过localStorage实现该功能,但不清楚具体实现逻辑。
  2. 如何在网站头部栏展示当前选中的语言(效果参考示例图:头部语言栏效果参考)?

实现方案

你现有代码里的localStorage逻辑是无效的:同一个key重复调用setItem会覆盖之前的值,而且你只做了存值操作,从来没有在页面加载时读取存储值应用配置,所以刷新后必然重置。另外你的变量声明有个小bug:lgmenu那行结尾用了分号,导致下一行的lglanguage没有声明关键字,会泄漏成全局变量,建议统一用逗号分隔变量声明。

1. 语言选择持久化实现

核心逻辑只有三个环节:用户切换语言时存值、页面加载时读值、读取后自动应用对应语言配置,不需要复杂操作。

  • 首先删掉你代码最后三行重复写setItem的无效代码
  • 抽离一个通用的语言切换函数,用户点击切换、页面初始化加载都复用这个逻辑,避免写重复代码
  • 页面初始化时优先读localStorage里存的语言值,没有存过就用默认语言(比如罗马尼亚语)
  • 用户点击语言选项时,除了更新页面文本,同步把选中的语言编码存入localStorage

对应可直接运行的代码:

let langs = document.querySelector(".langs"),
    links = document.querySelectorAll(".langs a"), // 缩小选择范围,避免误选页面其他a标签
    lgmenu = document.querySelector(".lgmenu"),
    lglanguage = document.querySelector(".lglanguage");

// 多语言配置
const data = {
  romanian: {
    lgmenu: "Meniu",
    lglanguage: "Alege limba"
  },
  english: {
    lgmenu: "Menu",
    lglanguage: "Choose language"
  }
};

// 通用语言切换方法
function changeLang(langCode) {
  // 容错:如果传入的语言不在配置里,回退到默认语言
  if (!data[langCode]) langCode = "romanian";
  // 更新页面文本
  lgmenu.textContent = data[langCode].lgmenu;
  lglanguage.textContent = data[langCode].lglanguage;
  // 更新语言选项的激活状态
  links.forEach(link => {
    link.classList.remove("active");
    if (link.getAttribute("language") === langCode) {
      link.classList.add("active");
    }
  });
  // 持久化存储用户选择
  localStorage.setItem("selectedLang", langCode);
  // 更新头部当前语言展示
  updateCurrentLangDisplay(langCode);
}

// 页面DOM加载完成后初始化
document.addEventListener("DOMContentLoaded", () => {
  // 读取本地存储的用户选择,没有则用默认语言
  const savedLang = localStorage.getItem("selectedLang") || "romanian";
  changeLang(savedLang);

  // 绑定语言选项点击事件
  links.forEach(link => {
    link.addEventListener("click", (e) => {
      e.preventDefault(); // 阻止a标签默认跳转/回到顶部的行为
      const targetLang = link.getAttribute("language");
      changeLang(targetLang);
    });
  });
});

2. 头部展示当前选中语言

实现分两步:

  • 第一步:在头部对应位置加展示用的DOM元素,放在语言下拉菜单的触发位置即可,示例结构:
<div class="header-lang-selector">
  <!-- 当前选中语言展示区 -->
  <div class="current-lang">
    <span class="current-lang-name"></span>
  </div>
  <!-- 你原来的语言选项列表 -->
  <div class="langs">
    <a href="#" language="romanian">Română</a>
    <a href="#" language="english">English</a>
  </div>
</div>
  • 第二步:写一个更新展示内容的方法,在每次切换语言(包括页面初始化)时调用即可,对应代码:
function updateCurrentLangDisplay(langCode) {
  const currentLangNameEl = document.querySelector(".current-lang-name");
  // 配置语言对应的展示文本,要加国旗的话也可以在这里加图片地址映射
  const langDisplayText = {
    romanian: "Română",
    english: "English"
  };
  currentLangNameEl.textContent = langDisplayText[langCode];
}

补充说明

  • 多页面场景下,每个页面都引入这段JS即可,所有页面加载时都会读同一个localStorage值,跨页面导航不会出现语言重置
  • 后续新增语言只需要在data配置对象、langDisplayText映射里加对应条目,不需要修改核心逻辑
  • 如果你需要做更复杂的多语言替换,可以给所有需要切换文本的DOM元素加自定义属性(比如data-i18n="lgmenu"),在changeLang方法里统一遍历替换,不用一个个手写选择器

内容的提问来源于stack exchange,提问作者FrontPower

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 09:51:30