What is the most efficient way to substitute text within an HTML document?

Is there a way to switch between languages on a website to replace text on multiple pages with a simple button click? What is the most efficient method for achieving this?

This code snippet only changes text in the first div. Is there a way to implement a language change feature that applies across the entire site?

var text1 = document.getElementById('english');
var text2 = document.getElementById('swedish');

const swap = () => {
  if (text1.classList.contains("hidden")) { //if english contains class 'hidden'
    text1.classList.remove("hidden"); //remove hidden class from english
    text2.classList.add("hidden"); //add hidden class to swedish
  } else {
    text1.classList.add("hidden"); //add hidden class to english
    text2.classList.remove("hidden"); //remove hidden class from swedish
  }
}
.hidden {
  display: none;
}
<button onclick="swap()">Switch Text</button>

<div class="content">
  <div id="english">
    <h1>Welcome</h1>
    <p>English text</p>
  </div>
  <div id="swedish" class="hidden">
    <h1>Vällkommen</h1>
    <p>Svensk tekst</p>
  </div>
</div>

Answer №1

  1. Remember to properly implement the use of the lang attribute
  2. Utilize classList.toggle for efficient toggling

This script should be added to all pages where the language is set to any of the specified languages.

Adjust the lang attribute as needed. Update lang="en"/lang="sv" in the script accordingly

Uncomment the lines with localStorage and eliminate the line: let savedLang = "se_SV"; from your site

window.addEventListener("DOMContentLoaded", () => {
  //let savedLang = localStorage.getItem("lang") || "gb_EN";
  let savedLang = "se_SV";
  const btn = document.getElementById("swap");
  btn.dataset.lang = savedLang;

  btn.addEventListener("click", (e) => {
    const tgt = e.target;
    let lang = tgt.dataset.lang;
    lang = lang === "gb_EN" ? "se_SV" : "gb_EN";
    tgt.dataset.lang = lang;
    // localStorage.setItem("lang",lang);
    const divs = document.querySelectorAll('div[lang]');
    divs.forEach(div => div.classList.toggle('hidden', div.lang === lang));
  })
  btn.click()
})
.hidden {
  display: none;
}
<button type="button" id="swap" data-lang="gb_EN">Switch Text</button>

<div class="content">
      <div lang="gb_EN">
        <h1>Welcome</h1>
        <p>English text</p>
      </div>
      <div lang="se_SV" class="hidden">
        <h1>Vällkommen</h1>
        <p>Svensk tekst</p>
      </div>
      <div lang="gb_EN">
        <h1>Welcome</h1>
        <p>English text</p>
      </div>
      <div lang="se_SV" class="hidden">
        <h1>Vällkommen</h1>
        <p>Svensk tekst</p>
      </div>
    </div>

Answer №2

[Edit 2023/04/24]

After some reflection, it seems that utilizing CSS to present the relevant content based on the lang attribute of the body could be the most efficient approach. Below is a simple code snippet demonstrating this concept.

For a demonstration of using the code with localStorage, refer to this Stackblitz snippet.

loadLanguage( {
  switchBtn: document.querySelector(`#langSwitch`),
  first: `sv-SE`, 
  second: `en-GB`} );

function loadLanguage( { switchBtn, first, second } ) {
  let currentLang; // currentLang not necessary with localStorage
  const store = {
    get current() { return currentLang ?? first; },
    set current(value) { document.body.lang = currentLang = value; } };
  const toggleLang = lang => 
    store.current = lang ?? (store.current === first ? second : first);
  switchBtn.addEventListener(`click`, () => toggleLang());
  toggleLang(store.current);
}
body {
  margin: 1rem;
  font-family: system-ui, sans-serif;
}

body[lang="en-GB"] [lang="sv-SE"] {
  display: none;
}


body[lang="sv-SE"] [lang="en-GB"] {
  display: none;
}

body[lang="en-GB"] [lang="en-GB"] {
  display: initial;
}

body[lang="sv-SE"] [lang="sv-SE"] {
  display: initial;
}


body[lang="sv-SE"] #langSwitch:after {
  content: 'Switch to english';
  margin-left: 36px;
}

body[lang="en-GB"] #langSwitch:after {
  content: 'Byta till svenska';
  margin-left: 36px;
}

body[lang="sv-SE"] #langSwitch {
  background: url(https://upload.wikimedia.org/wikipedia/commons/8/83/Flag_of_the_United_Kingdom_%283-5%29.svg) no-repeat 6px center;
  background-size: 32px;
}

body[lang="en-GB"] #langSwitch {
  background: url(https://upload.wikimedia.org/wikipedia/commons/4/4c/Flag_of_Sweden.svg) no-repeat 6px center;
  background-size: 32px;
  border: none;
}

#langSwitch {
  display: initial;
  border: none;
  padding: 8px;
  box-shadow: -2px -2px 4px #aaa inset;
  border-radius: 3px;
}

#langSwitch:hover {
  box-shadow: 2px 2px 4px #aaa inset;
}

button {
  margin-bottom: 0.5rem;
}
<button id="langSwitch" lang="sv-SE"></button>
<div lang="en-GB">
  <h1>Welcome</h1>
  <p>English text</p>
</div>

<div lang="sv-SE">
  <h1>Vällkommen</h1>
  <p>Svensk tekst</p>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What are the steps to create a JSON file structured in a tree format?

Can you provide instructions on creating a JSON file in the following tree format? root child1 child11 child2 child21 child22 child3 child31 I am looking to generate a sample JSON file that adheres to the ...

Display various components using a dropdown selection

I am seeking guidance on how to display different components based on the selected option. I am unsure of how to write the code for displaying either component one or two. Can you provide any examples or references that may help? <template> <div ...

Experiencing a missing handlebars helper error when utilizing a helper within partials in express-handlebars

I have set up custom helpers using express-handlebars like this: const { create } = require("express-handlebars"); // Configuring the handlebars engine const hbs = create({ helpers: require("./config/handlebars-helpers"), }); app.engi ...

Issue with Next.js: Setting the width to 100vh prevents the height from being responsive on mobile devices

While I understand that using height: 100vh on mobile is generally discouraged for various reasons, I'm curious as to why height: 100vh paired with width: 100vh in Next.js doesn't produce the expected result. Instead of a full-height square, I en ...

Managing numerous invocations of an asynchronous function

I have an imported component that triggers a function every time the user interacts with it, such as pressing a button. Within this function, I need to fetch data asynchronously. I want the function calls to run asynchronously, meaning each call will wait ...

Ways to streamline the directives for conciseness?

This section contains a login field where users can input their username, password, and click the login button. It may seem lengthy and detailed at first glance. <form name='form' novalidate ng-submit="form.$valid && submit('/log ...

PHP Header Redirect Not Redirecting Correctly

As a newcomer to PHP, I conducted some research and attempted to implement a solution found on Stack Overflow, but unfortunately, it did not work for me. My goal is to redirect users to another page after a specific code has been executed. Despite removing ...

The function forEach is unable to handle the process of uploading multiple images to cloudinary

I'm facing an issue with uploading multiple images to Cloudinary from my Vue2JS front-end. I have successfully created a function that uploads a single image, but I am struggling with uploading multiple images using a forEach loop. upload(evt) { ...

Personalized AngularJS required text

After utilizing the built-in AngularJS directive required and encountering a validation error, I receive a small popup near the field displaying "Please fill out this field". My issue lies in needing the text to be displayed in another language. How should ...

Ways in which the user can modify the city name within this inquiry

I am just beginning to learn JavaScript and I am struggling to figure out how to allow the user to change the city name in this request. Currently, it works when I manually input the city name in the code (e.g., askWeather.open("GET", "url.../london")), bu ...

What is the best way to handle newline characters ( ) when retrieving text files using AJAX?

When using an AJAX call to read a text file, I encountered an issue where it reads the \n\t and backslash symbols. These characters are not needed in the pure text message. How can I ignore or remove them for a clean text display? ...

Manipulating State in React: How to add a property to an object within an array within a component's state

Currently, I am retrieving an array of objects stored in the state, and I am attempting to include a new property to each of these objects. However, I am encountering a problem where even though I can see the new property being added to each object, when ...

Guide to establishing intricate conditions for TypeORM insertion

When attempting to insert data based on a specific condition, such as if shopId = "shopA", I want to include the shopdetail. In order to achieve this, I have implemented the following business logic, which is somewhat complex. Is there a more ef ...

When implementing `useRouter().push()` in Next.js, it has the ability to refresh

I have recently started using a custom node server in my Next.js app. Previously, useRouter().push() was working fine without a custom server and providing a seamless single-page app experience. However, with the custom server, it now refreshes my applicat ...

What could be causing the unresponsive hamburger button on my navbar?

As a beginner in HTML and Flask, I am attempting to create a navbar. However, I am encountering an issue with the hamburger button not functioning properly. When I resize the window smaller, the hamburger button appears but does not show the items like "Lo ...

Retrieving information from the backend using JavaScript

Utilizing devexpress JS Charts requires data to be in the format: [{ category: 'Oceania', value: 35 },{ category: 'Europe', value: 728 }] To achieve this format, I convert a DataTable to JSON in my backend code after running queries b ...

What's the best way to implement asynchronous state updating in React and Redux?

In my React incremental-style game, I have a setInterval function set up in App.ts: useEffect(() => { const loop = setInterval(() => { if (runStatus) { setTime(time + 1); } }, rate); return () => clearInterval(lo ...

Error: Vue.js is unable to find the reference for "_vm.KisanData" and throws a TypeError

I need assistance in fixing an error that I am encountering. The issue arises in this method where I am using KisanData, but I am unable to resolve it. const API_URL = "http://localhost:3000/User"; export default { name: "home", info(){ ...

How can I iterate through a directory containing files and extract the exported JavaScript object from each one?

In my current project using nodejs / nextjs, I have file system access and a folder containing multiple React files: content - blog-post-1.jsx - blog-post-2.jsx - blog-post-3.jsx The task at hand is to extract the frontmatter from each file. My init ...

Encountered the error message "A property 'split' cannot be read of undefined" while attempting to run a React Native application

I was able to run a react-native app without any issues yesterday, but today when I tried to run it again, I encountered some problems. After running "npm start" to start metro, I then attempted to run "npx react-native run-android". However, I received th ...