javascript 如何通过覆盖全局CSS的JS实现语言选择器

cqoc49vn  于 2023-11-15  发布在  Java
关注(0)|答案(4)|浏览(186)

我想创建一个简单的基于CSS的语言切换器。
考虑一个静态HTML页面,其中包含3种语言的内容:

<h1 lang="en">Hello World</h1>
<h2 lang="de">Hallo Welt</h1>
<h2 lang="fr">Bonjour la Mond</h1>
...
<p lang="en">This is my english webpage...</p>
<p lang="de">Dies ist meine deutsche Webseite...</p>
<p lang="fr">Je ne parles pas francais</p>

字符串
当页面加载时,我们希望检测用户的语言(navigator.language || navigator.userLanguage),并只显示:lang(en)元素,隐藏所有德语或法语部分。

*[lang=en] {display:block}
*[lang=de] {display:none}
*[lang=fr] {display:none}


现在,如果用户选择German,我们需要一些JavaScript全局切换样式表(而不是按元素),这样我们就可以覆盖上面的CSS:

*[lang=en] {display:none}
*[lang=de] {display:block}
*[lang=fr] {display:none}


如何在JavaScript中全局实现这样的CSS覆盖?
备注:

  • 我不想选择HTML元素并切换它们的显示-我想覆盖全局CSS。
  • 如何选择语言是无关紧要的-它将是触发JS的onclickonchange事件
  • 我不介意所有的lang元素都显示为块,尽管如何在none<original>之间切换它们的显示属性而不丢失display:inline会很有趣。
n6lpvg4x

n6lpvg4x1#

我能想到的一种实现方法是为各种语言创建单独的样式表,然后通过编程在它们之间切换。
1.为每种语言创建单独的css文件。(你可以把display:block*[lang=de] {display: block}到german.css和其他none等等)

/* english.css */
 *[lang=en] {display:block}
 *[lang=de] {display:none}
 *[lang=fr] {display:none}

字符串
1.添加到你想保留为默认的css文件的链接。同时提供一个Id

<link id="languageStylesheet" rel="stylesheet" type="text/css" href="english.css">


1.创建一个函数来根据所选语言切换样式表。setAttribute 是键。

function switchLanguage(lang) {
let stylesheetUrl;
switch (lang) {
  case 'en':
    stylesheetUrl = 'english.css';
    break;
  case 'de':
    stylesheetUrl = 'german.css';
    break;
  case 'fr':
    stylesheetUrl = 'french.css';
    break;
  default:
    stylesheetUrl = 'english.css';
}
 document.getElementById('languageStylesheet').setAttribute('href', stylesheetUrl);
}
  • 代码演示 *
zf9nrax1

zf9nrax12#

传统的方法是在一个共同的祖先元素(如<html><body>元素)上设置一个类或数据属性。
假设我们使用一个data属性,并将其命名为data-user-lang
然后你的JS只需要通过任何你想要的选择器代码将这个属性的值设置为'en','de'或'fr'。
所有你需要的是一个单一的CSS规则:

[data-user-lang=en] [lang]:not([lang=en]),
[data-user-lang=de] [lang]:not([lang=de]),
[data-user-lang=fr] [lang]:not([lang=fr]) { 
  display: none;
}

字符串
具有lang属性的每个元素的显示值与所选语言相匹配将被保留。

hgtggwj0

hgtggwj03#

我只能说这是一个昂贵的想法,但基本上是可行的

const languages = ["en", "de", "fr", "ja"]

function changeLanguage(language) {
  if (!languages.includes(language)) language = languages[0]

  const style = document.querySelector("[data-type=css-language]") ?? document.createElement('style')
  style.textContent = `[lang="${language}"] { display: block }`
  style.setAttribute("data-type", "css-language")
  document.body.appendChild(style)
}


changeLanguage(navigator.language)
[lang] { display: none }
<h1 lang="en">Hello World</h1>
<h2 lang="de">Hallo Welt</h1>
<h2 lang="fr">Bonjour la Mond</h1>
<h2 lang="ja">こにちは</h1>
...
<p lang="en">This is my english webpage...</p>
<p lang="de">Dies ist meine deutsche Webseite...</p>
<p lang="fr">Je ne parles pas francais</p>
<p lang="ja">私わオタク</p>

<button onclick="changeLanguage('ja')">Switch to Japanese</button>
qpgpyjmq

qpgpyjmq4#

另一种方法是使用CSS变量而不使用多个样式表,或者重写样式。一个固定的样式表是由JavaScript在pagload中创建的,包含变量和规则。
要应用样式,我们只需要根据语言设置CSS变量。
在下面的演示中,语言是由一个组合框选择的,只是为了显示功能,可以简单地通过navigator.language编辑设置。

function init() {
  const style = document.documentElement.style;
  const ss = document.getElementById("ss").sheet;
  const langs = document.querySelectorAll("#langs > option");
  for (var i = 0; i < langs.length; i++) {
    ss.insertRule(`[lang=${langs[i].value}] {display: var(--${langs[i].value});}`, i+1);
    // add CSS rule
    if (langs[i].selected) {
      var display = 'block';
    } else {
      var display = 'none';
    }
    style.setProperty('--' + langs[i].value, display);
    // add CSS variable
  }
  ss.removeRule(0);
  document.getElementById("langs").addEventListener('change', SetLanguage); 
}

function SetLanguage(value) {
  const selectedLanguage = document.querySelector("#langs").value;
  const langs = document.querySelectorAll("#langs > option");
  for (let lang of langs) {
    if (lang.value == selectedLanguage) {
      var display = 'block';
    } else {
      var display = 'none';
    }
    document.querySelector(':root').style.setProperty('--' + lang.value, display);
  }
}

window.addEventListener('load', init);

个字符
样式最初为空,但有一个id,所以我们可以访问它并在pageload事件中添加规则。在这个演示中,语言列表是从组合框中构建的,它可以简单地被数组替换。创建的样式相当于:

<style>
    :root {
        --en:block;
        --fr:none;
        --de:none;
        --fa:none;
    }

    [lang=en] {display: var(--en);}

    [lang=de] {display: var(--de);}

    [lang=fr] {display: var(--fr);}

    [lang=fa] {display: var(--fa);}
</style>


要显示选定的语言元素,我们只需将相应的CSS变量设置为显示,并将所有其他变量设置为无。

相关问题