skip to Main Content

I am trying to create a website that can switch languages from English to French by clicking on the toggle button. I tried a few ways without Javascript because I don’t know much, and only with CSS but never found the result I wanted.

Only The <h2 class="title">welcome!</h2>changes to "yoohoo les nazes", but the rest does not change.

Can anyone help?

document.querySelector('#togBtn').addEventListener('input', (event) => {
  document.querySelector('.title', '.1', '.2', '.3', '.4', '.5').textContent = data[event.currentTarget.checked ? 'francais' : 'english'].title;
  .1;
});
var data = {
  "english": {
    "title": "welcome!",
    "1": "My work is primarily inspired by nature.",
    "2": "Each creation is unique.",
    "3": "The white porcelain I use",
    "4": "I studied and graduated",
    "5": "I wish to thank"
  },
  "francais": {
    "title": "yoohoo les nazes",
    "1": "Mon travail est d'abord inspiré sur la nature.",
    "2": "chaque création est unique.",
    "3": "La porcelaine blanche que j'utilise",
    "4": "j'ai étudiée et sui diplômée",
    "5": "j'aimerai remercier"
  }
}
.switch {
  position: relative;
  display: inline-block;
  width: 80px;
  height: 34px;
}

.switch input {
  display: none;
}

.slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: brown;
  -webkit-transition: .4s;
  transition: .4s;
}

.slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

input:checked+.slider {
  background-color: burlywood;
}

input:focus+.slider {
  box-shadow: 0 0 1px #2196F3;
}

input:checked+.slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(45px);
}

.slider {
  border-radius: 34px;
}

.slider:before {
  border-radius: 50%;
}

.on {
  display: none;
}

.on,
.off {
  color: white;
  position: absolute;
  transform: translate(-50%, -50%);
  top: 50%;
  left: 50%;
  font-size: 10px;
  font-family: Verdana, sans-serif;
}

input:checked+.slider .on {
  display: block;
}

input:checked+.slider .off {
  display: none;
}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Whisper&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer"
/>

<label class="switch">       
  <input type="checkbox" id="togBtn">       
  <div class="slider round">         
    <span language='english' class="on">EN</span>         
    <span language='francais' class="off">FR</span>       
  </div>     
</label>
<ul class="nav-items">
  <div class="content">
    <h2 class="title">welcome!</h2>
    <p class="1">My work is primarily inspired by nature.</p>
    <p class="2">Each creation is unique.</p>
    <p class="3">The white porcelain I use</p>
    <p class="4">I studied and graduated </p>
    <p class="5">I wish to thank</p>
  </div>
</ul>

2

Answers


  1. The first issue you have is that document.querySelector() can only select a single element. To select multiple elements you should use querySelectorAll() instead. However the syntax you used is incorrect. You need to provide a single string selector, not multiple arguments, eg:

    document.querySelector('.title, .element1, .element2, .element3, .element4, .element5');
    

    To improve the code quality you can use a single common class which you put on all elements to be translated, I used .translate in the following example. From there you can loop over all of those elements and use a data attribute to provide the ‘key’ of the translation to use for that specific element.

    In addition, note that the EN and FR labels in the toggle were inverted for the actual language being shown.

    Finally, as noted by @CBroe in the comments, browsers are tolerant of class and id values which are numeric, however it’s outside of the spec and not good practice. I’ve converted these to alpha-numeric values instead.

    Here’s a working example with the above changes made:

    document.querySelector('#togBtn').addEventListener('change', e => {
      document.querySelectorAll('.translate').forEach(el => {
        el.textContent = data[e.target.checked ? 'francais' : 'english'][el.dataset['tkey']];
      });
    });
    
    var data = {
      "english": {
        "title": "welcome!",
        "para-01": "My work is primarily inspired by nature.",
        "para-02": "Each creation is unique.",
        "para-03": "The white porcelain I use",
        "para-04": "I studied and graduated",
        "para-05": "I wish to thank"
      },
      "francais": {
        "title": "yoohoo les nazes",
        "para-01": "Mon travail est d'abord inspiré sur la nature.",
        "para-02": "chaque création est unique.",
        "para-03": "La porcelaine blanche que j'utilise",
        "para-04": "j'ai étudiée et sui diplômée",
        "para-05": "j'aimerai remercier"
      }
    }
    .switch {
      position: relative;
      display: inline-block;
      width: 80px;
      height: 34px;
    }
    
    .switch input {
      display: none;
    }
    
    .slider {
      position: absolute;
      cursor: pointer;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: brown;
      -webkit-transition: .4s;
      transition: .4s;
    }
    
    .slider:before {
      position: absolute;
      content: "";
      height: 26px;
      width: 26px;
      left: 4px;
      bottom: 4px;
      background-color: white;
      -webkit-transition: .4s;
      transition: .4s;
    }
    
    input:checked+.slider {
      background-color: burlywood;
    }
    
    input:focus+.slider {
      box-shadow: 0 0 1px #2196F3;
    }
    
    input:checked+.slider:before {
      -webkit-transform: translateX(26px);
      -ms-transform: translateX(26px);
      transform: translateX(45px);
    }
    
    .slider {
      border-radius: 34px;
    }
    
    .slider:before {
      border-radius: 50%;
    }
    
    .on {
      display: none;
    }
    
    .on,
    .off {
      color: white;
      position: absolute;
      transform: translate(-50%, -50%);
      top: 50%;
      left: 50%;
      font-size: 10px;
      font-family: Verdana, sans-serif;
    }
    
    input:checked+.slider .on {
      display: block;
    }
    
    input:checked+.slider .off {
      display: none;
    }
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Whisper&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer"
    />
    
    <label class="switch">       
      <input type="checkbox" id="togBtn">       
      <div class="slider round">         
        <span class="on">FR</span>         
        <span class="off">EN</span>       
      </div>     
    </label>
    <ul class="nav-items">
      <div class="content">
        <h2 class="translate" data-tkey="title">welcome!</h2>
        <p class="translate" data-tkey="para-01">My work is primarily inspired by nature.</p>
        <p class="translate" data-tkey="para-02">Each creation is unique.</p>
        <p class="translate" data-tkey="para-03">The white porcelain I use</p>
        <p class="translate" data-tkey="para-04">I studied and graduated </p>
        <p class="translate" data-tkey="para-05">I wish to thank</p>
      </div>
    </ul>
    Login or Signup to reply.
  2. Apart from the perfect solution offered by @Rory McCrossan I am proposing another solution using useful ‘wildcard selectors’ and array index, without data attribute

    let checkBox = document.querySelector('#togBtn')
    
    var data = {
        "english": {
          "0": "welcome!",
          "1": "My work is primarily inspired by nature.",
          "2": "Each creation is unique.",
          "3": "The white porcelain I use",
          "4": "I studied and graduated",
          "5": "I wish to thank"
        },
        "francais": {
          "0": "yoohoo les nazes",
          "1": "Mon travail est d'abord inspiré sur la nature.",
          "2": "chaque création est unique.",
          "3": "La porcelaine blanche que j'utilise",
          "4": "j'ai étudiée et sui diplômée",
          "5": "j'aimerai remercier"
        }
      }
    
    
    checkBox.addEventListener('change', () => {
        let elemToChange = document.querySelectorAll('[class^="myclass"]')
        elemToChange.forEach((elem,idx)=>{
            elem.innerHTML=data[checkBox.checked ? "francais" : "english"][idx]
        })
      });
    .switch {
        position: relative;
        display: inline-block;
        width: 80px;
        height: 34px;
      }
      
      .switch input {
        display: none;
      }
      
      .slider {
        position: absolute;
        cursor: pointer;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background-color: brown;
        -webkit-transition: .4s;
        transition: .4s;
      }
      
      .slider:before {
        position: absolute;
        content: "";
        height: 26px;
        width: 26px;
        left: 4px;
        bottom: 4px;
        background-color: white;
        -webkit-transition: .4s;
        transition: .4s;
      }
      
      input:checked+.slider {
        background-color: burlywood;
      }
      
      input:focus+.slider {
        box-shadow: 0 0 1px #2196F3;
      }
      
      input:checked+.slider:before {
        -webkit-transform: translateX(26px);
        -ms-transform: translateX(26px);
        transform: translateX(45px);
      }
      
      .slider {
        border-radius: 34px;
      }
      
      .slider:before {
        border-radius: 50%;
      }
      
      .on {
        display: none;
      }
      
      .on,
      .off {
        color: white;
        position: absolute;
        transform: translate(-50%, -50%);
        top: 50%;
        left: 50%;
        font-size: 10px;
        font-family: Verdana, sans-serif;
      }
      
      input:checked+.slider .on {
        display: block;
      }
      
      input:checked+.slider .off {
        display: none;
      }
    <body>
        <label class="switch">       
        <input type="checkbox" id="togBtn">       
        <div class="slider round"> 
            <span language='english' class="off">En</span>  
            <span language='francais' class="on">Fr</span>  
                           
        </div>     
        </label>
        <ul class="nav-items">
        <div class="content">
            <h2 class="myclass0">welcome!</h2>
            <p class="myclass1">My work is primarily inspired by nature.</p>
            <p class="myclass2">Each creation is unique.</p>
            <p class="myclass3">The white porcelain I use</p>
            <p class="myclass4">I studied and graduated </p>
            <p class="myclass5">I wish to thank</p>
        </div>
        </ul>
    </body>

    .

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search