JavaScript: Modifying the Style of a :lang Selector

Currently, I am working on creating a basic multilingual static website using only HTML5, CSS3, and vanilla JavaScript. The structure of the HTML looks something like this:

<html>
      <head>
        <title>WEBSITE</title>
      </head>
      <body>
        <header>
          <h1 lang="en">ENGLISH HEADER</h1>
          <h1 lang="fr">FRENCH HEADER</h1>
          ...
        </header>
        <main>
          <article lang="en"><p>...</p></article>
          <article lang="fr"><p>...</p></article>
          ...
        </main>
      </body>
    </html>
    

By default, my website is set to display in English. To achieve this, I have added the following CSS:

header h1:not(:lang(en)), main article:not(:lang(en)) {
      display: none;
    }
    

As users can change their preferred language using a <select> element with an onChange="" event that triggers a JavaScript function. Although I am not very familiar with JavaScript, I am curious to know if it's possible to update the styling based on the user's selected language without using any frameworks or libraries.

I have intentionally chosen to avoid using JS frameworks and jQuery to keep the website as straightforward as possible. Any suggestions on achieving this would be greatly appreciated.

Answer №1

Here is an alternative method that parallels your initial CSS strategy. To begin, we set a global/body-level lang attribute with a value of en as the default.

Subsequently, applying our CSS would look like this:

body[lang="en"] [lang="fr"],
body[lang="fr"] [lang="en"]{
    display: none;
}

The opposite approach (using :not) can be achieved through:

body[lang=en] [lang]:not([lang=en]),
body[lang=fr] [lang]:not([lang=fr]) {
    display: none;
}

When it comes to altering the body-level lang attribute in the select handler, it is a straightforward task:

function langChange(el) {
  document.body.setAttribute('lang', el.value);
}

Allow me to provide you with a testable snippet below:

function langChange(el) {
  document.body.setAttribute('lang', el.value);
}
body[lang="en"] [lang="fr"],
body[lang="fr"] [lang="en"]{
  display: none;
}
<body lang="en">
  <header>
    <h1 lang="en">ENGLISH HEADER</h1>
    <h1 lang="fr">FRENCH HEADER</h1>
    ...
  </header>
  <main>
    <article lang="en">
      <p>English Paragraph</p>
    </article>
    <article lang="fr">
      <p>French Paragraph</p>
    </article>
    ...
  </main>
  <select onChange="langChange(this)">
    <option selected value="en">English</option>
    <option value="fr">French</option>
  </select>
</body>

(An instance demonstrating the application of :not and generating selectors with a CSS preprocessor can be observed here: https://jsfiddle.net/o7vxskzL/)

Answer №2

I think I have discovered a solution, although I'm not sure if it's the most efficient method, it gets the job done.

Essentially, what I did was target all elements that are not langX using

document.querySelectorAll("tag:not(lang(langX))")
, then made them invisible. Next, I made all langX elements visible in a similar manner.

Surprisingly, it was quite straightforward.

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

Is it possible to execute the Go compiler within a web browser?

Just discovered that Go can be compiled to WebAssembly. How awesome! According to this Go documentation, the Go toolchain is actually written in Go itself. This got me thinking, is it possible to run the Go compiler in a browser? Can I create a website w ...

Error message: Uncaught TypeError - Unable to access property value from null reference in Quicksort.js

Can someone assist me in resolving the "uncaught typeerror cannot read property of null" issue I'm facing on line 4 of my JavaScript code? This is my first post on this platform and I hope to find some help here! function sort() { var array = docume ...

Maintain parent hover effect while child is being hovered over

After exploring various solutions to fix an issue, I've hit a roadblock. Adding CSS and jQuery code seemed promising at first, but upon refreshing the browser, a new problem emerged. The parent element retained its hover state background color, but th ...

Comparison between UI Router and ngRoute for building single page applications

Embarking on a new Angular project, a single page app with anticipated complex views such as dialogs, wizards, popups, and loaders. The specific requirements are yet to be clarified. Should I embrace ui.router from the start? Or begin with ngRoute and tra ...

ReactJS: The function .useSelector() is not defined

I've been following a tutorial for a while and hit a roadblock trying to understand this. Both metaphorically and literally. On the Dashboard page, I attempted to use useSelector() to access the state of the goalSlice component. This component is ver ...

Express router parameter matching

Let's consider a scenario where I have two routes - one with parameters and one without: /foo?bar /foo I aim to assign different handlers for these routes. Instead of the conventional approach, I am looking for a way to simplify the code. app.use(&a ...

What is the best way to swap out an observable array with an array retrieved from an API response

I have a custom material autocomplete input that allows users to select items in a dynamic form component. Since the fields of the form are dynamic, I need to filter the list of items every time a user types something into the input. filteredOptions: { [k ...

Display JSON information in a table using AngularJS

As I delve back into an old project, I've encountered a hurdle. My goal is to display some data in a table, but I seem to have forgotten the intricacies of working with JSON objects and Angular. The API response I'm receiving looks something lik ...

Guide for overlaying text on an image in react native

Is there a way to vertically align text over an image in react native? I came across this helpful guide, but I encountered difficulties trying to implement it. Specifically, I couldn't figure out how to nest the text tag within the Image tag. Below is ...

Executing a jQuery AJAX request for a second time

Upon hitting the submit button for the first time, the codes work successfully. However, upon hitting the button for the second time with correct email and password values, nothing happens and the user cannot log in. I have identified that the issue lies w ...

Utilizing Jquery's fadeIn() function to make elements appear gradually on the webpage, whether

New Question: Is there a way to smoothly transition the visibility of a div element without using display:none or CSS, as these methods remove the div from view rather than simply hiding it, causing elements below to shift? If I try setting opacity:0 or v ...

Unlocking a targeted list in AngularJS

I have the following code snippet that I am using to implement ng-repeat in an Angular project. My goal is to display only the list item that I click on, but currently, when I click on the symbol ~, it displays all the lists. Is there a way to specify cer ...

Base64 versus UTF-8 charset: What sets them apart?

While working with binary files, I discovered that: If it's a text-based file, I need to use data:text/plain;charset=utf-8, and if it's a multimedia file, I should use data:image/png;base64, I attempted to use base64 encoding and encountered a ...

"Counting the clicks on the filter button in React

I have: var RightPanel = React.createClass({ componentDidMount: function () { this.load(); }, load: function(){ }, render: function () { return ( <div> <div className="row"> ...

Sending values to Vuex getters from a Vuex action

I have been utilizing a Vuex getter across various components in my application. However, I recently encountered a scenario where I require slightly more intricate logic before accessing the getter, leading me to employ a Vuex Action. The challenge now is ...

Vue.js has a feature where it automatically closes the form tag within a for loop

In my Vue.js application, I have created a table where each row is a form with a submit button. This is the code snippet I am using: <div id="admin-user"> <table class="table"> <tr v-for="(user, index) in users"> < ...

When setting the height to auto in Dreamweaver for a background image, no content will be displayed

I have been searching through several questions on this platform today in the hopes of finding an answer to my query, but unfortunately, I haven't had any luck so far. That's why I'm turning to you all for help. My current goal is to transi ...

Can you explain how to create a function in Angular that accepts a number as an argument and then returns the square of that number?

I am working with an array of numbers and I want to show each number in the list along with its square value. To do this, I need to create a function that takes a number as input and returns its square as output. Here is what I have attempted so far: co ...

Inaccurate Guild Member Filtering

Recently, I've been working on creating a unique member counter for my server. The goal is to accurately count the total number of members in the server, excluding bots, and counting only bots as well. However, when I attempt to display these counts i ...

How can I resize and horizontally align an image using html/css?

Is it possible to resize, crop and center an image using only HTML/CSS? (Using the img tag or CSS sprite) For instance, if I have a 500x500 pixel image, I would like to resize it to a 250x250 pixel image To make the actual visible image 100x100 pixe ...