I'm building a Website in HTML, CSS, and JS. I used this template for getting started: https://html5up.net/landed
Now when resizing the Window the Navbar at the top gets transformed to a dropdown Menu (or Burger Menu).
I'm trying to solve a problem where I can insert the Text from my translation file to the listItems within the transformed Navigation. I am very confused how this transformation happens and how i can for example make it happen on another MediaQuery as well.
"en": {
"home": "Home",
// other translations...
},
"de": {
"home": "Startseite",
// other translations...
}
I use this to set and toggle my translations which works great:
let translations;
// Function to toggle language
const toggleLanguage = (language) => {
const elements = document.querySelectorAll('[data-translate]');
elements.forEach((element) => {
const key = element.getAttribute('data-translate');
element.innerHTML = translations[language][key] || translations['en'][key];
});
};
// Function to load translations from the JSON file
const loadTranslations = () => {
fetch('assets/js/translations.json')
.then(response => response.json())
.then(data => {
translations = data;
const savedLanguage = localStorage.getItem('selectedLanguage') || 'de';
document.documentElement.lang = savedLanguage;
toggleLanguage(savedLanguage);
// Add 'active' class to the saved language link
const savedLangLink = document.querySelector(`[data-lang="${savedLanguage}"]`);
if (savedLangLink) {
savedLangLink.classList.add('active');
}
})
.catch(error => console.error('Error loading translations:', error));
};
// Event listener for language toggle links
document.querySelectorAll('.lang-toggle').forEach((link) => {
link.addEventListener('click', (event) => {
event.preventDefault();
const newLanguage = event.target.getAttribute('data-lang');
document.documentElement.lang = newLanguage;
toggleLanguage(newLanguage);
// Remove 'active' class from all links
document.querySelectorAll('.lang-toggle').forEach((link) => {
link.classList.remove('active');
});
// Add 'active' class to the clicked link
event.target.classList.add('active');
// Save the selected language to localStorage
localStorage.setItem('selectedLanguage', newLanguage);
});
});
// Load translations when the DOM is ready
document.addEventListener('DOMContentLoaded', loadTranslations);
Here's my Nav:
<header id="header">
<h1 id="logo" style="font-size: 200%; font-family:logoFont;"><a href="index.html">JS</a></h1>
<nav id="nav">
<ul style="font-weight: bold;">
<li><a href="index.html" data-translate="home"></a></li>
<li><a data-translate="aboutNav" href="#about" class="scrolly"></a></li>
<li><a data-translate="services" href="#services" class="scrolly"></a></li>
<li><a data-translate="skills" href="#skills" class="scrolly"></a></li>
<li><a data-translate="career" href="#career" class="scrolly"></a></li>
<li style="padding-left: 7em;"><a data-translate="de" href="#" class="lang-toggle" data-lang="de">DE</a></li>
<li style="margin-left: -0.01em;"><a data-translate="en" href="#" class="lang-toggle" data-lang="en">EN</a></li>
</ul>
</nav>
</header>
Now, when I resize the window, this MediaQuery takes action:
/* Small */
#navPanel,
#titleBar {
display: none;
}
@media screen and (max-width: 980px) {
/* Basic */
html,
body {
overflow-x: hidden;
}
/* ... (other CSS rules) ... */
/* Nav */
#page-wrapper {
-moz-backface-visibility: hidden;
-webkit-backface-visibility: hidden;
-ms-backface-visibility: hidden;
backface-visibility: hidden;
-moz-transition: -moz-transform 0.5s ease;
-webkit-transition: -webkit-transform 0.5s ease;
-ms-transition: -ms-transform 0.5s ease;
transition: transform 0.5s ease;
padding-bottom: 1px;
padding-top: 44px !important;
}
#titleBar {
/* ... (titleBar styles) ... */
}
#navPanel {
/* ... (navPanel styles) ... */
}
/* ... (other CSS rules) ... */
}
And the Nav
element transforms into a dropdown:
Main.js
// Nav.
$(
'<div id="titleBar">' +
'<a href="#navPanel" class="toggle"></a>' +
'<span class="title">' + $('#logo').html() + '</span>' +
'</div>'
).appendTo($body);
Util.js
$.fn.navList = function (translationData, language) {
var $this = $(this);
$a = $this.find('a'),
b = [];
$a.each(function () {
var $this = $(this),
indent = Math.max(0, $this.parents('li').length - 1),
href = $this.attr('href'),
target = $this.attr('target'),
translationKey = $this.data('translate').toLowerCase(); // Get translation key from data-translate attribute
console.log('Translation Key:', translationKey);
console.log('Translation Data:', translationData);
// Find translation for the key in the provided translation data
var translatedText = translationData[language][translationKey] || translationKey;
b.push(
'<a ' +
'class="link depth-' + indent + ' scrolly"' + // Add 'scrolly' class
( (typeof target !== 'undefined' && target != '') ? ' target="' + target + '"' : '') +
( (typeof href !== 'undefined' && href != '') ? ' href="' + href + '"' : '') +
' data-translate="' + translationKey + '">' + // Set data-translate attribute
'<span class="indent-' + indent + '"></span>' +
translatedText + // Use translated text
'</a>'
);
});
return b.join('');
};
var translationData = {
"en": {
"home": "Home",
// other translations...
},
"de": {
"home": "Startseite",
// other translations...
}
};
// Callback function to initialize navigation after translation data is loaded
function initNavigation() {
$('#nav').html($('#nav').navList(translationData, 'en')); // Example usage
// Other initialization code for your navigation...
}
// Simulate loading translation data asynchronously (replace this with your actual data loading mechanism)
setTimeout(function() {
initNavigation();
}, 1000);
What I'm trying to solve is the <li>
elements within the transformed Nav don't have any text because the data-translate
doesn't get passed with the transformation. Also, when I try to transform the Navbar in a different MediaQuery, I can't get it to work. Is there anyone who can make sense out of this? If I should provide additional code, please let me know. Thanks in advance!