I have this simple page set up which will add or remove a hidden class on an element when either button is clicked. The code works fine as is, but I know that it's very inefficient. I plan on adding more buttons and don't want to make a new function and event listener for each one. Rather than having a separate function for each button I would like to make 1 function which can differentiate which button was pressed and add the hidden class based on that. Any ideas?
<style>
.hidden {
display: none;
}
</style>
<body>
<header>
<button >Home</button>
<button >About</button>
</header>
<main>
<h1 >This is the Home Page</h1>
<h1 >This is the About Page</h1>
</main>
<script>
const navLink = document.querySelectorAll('.nav-link');
const linkHome = document.querySelector('.link-home');
const linkAbout = document.querySelector('.link-about');
const mainContent = document.querySelectorAll('.main-content');
const homePage = document.querySelector('.home-page');
const aboutPage = document.querySelector('.about-page');
const openHome = () => {
homePage.classList.remove('hidden');
aboutPage.classList.add('hidden');
};
linkHome.addEventListener('click', openHome);
const openAbout = () => {
aboutPage.classList.remove('hidden');
homePage.classList.add('hidden');
};
linkAbout.addEventListener('click', openAbout);
</script>
</body>
CodePudding user response:
You can use data
attribute to link each link
with its corresponding page, and add event listner for all links
that have the data-link
attribute and on click
get the value of data-link
and querySelector
the data-page
with this value, then add
hidden class to all links and remove
hidden class from the target page.
<style>
.hidden {
display: none;
}
</style>
<body>
<header>
<button data-link="home">Home</button>
<button data-link="about">About</button>
</header>
<main>
<h1 data-page="home">This is the Home Page</h1>
<h1 data-page="about">This is the About Page</h1>
</main>
<script>
const links = document.querySelectorAll('[data-link]');
const pages = document.querySelectorAll('[data-page]');
links.forEach(link => {
link.addEventListener('click', () => {
pages.forEach(page => page.classList.add('hidden'));
const page = document.querySelector(`[data-page="${link.dataset.link}"]`);
page.classList.remove('hidden');
})
})
</script>
</body>
CodePudding user response:
You can do something like this:
const open = (className) => {
const page = document.getElementsByClassName(className)[0];
page.classList.remove('hidden');
page.classList.add('hidden');
};
CodePudding user response:
You can write a generic event handler which - when called - makes all .main-content
hidden and then unhides the relevant .main-content
based on (for example) the button text:
const navLink = document.querySelectorAll('.nav-link');
const mainContent = document.querySelectorAll('.main-content');
navLink.forEach(l => l.addEventListener('click', (e) => {
// hide all divs
mainContent.forEach(c => c.classList.add('hidden'))
// show the one of interest
content = `.${e.target.textContent.toLowerCase()}-page`
document.querySelector(content).classList.remove('hidden')
}))
.hidden {
display: none;
}
<body>
<header>
<button >Home</button>
<button >About</button>
</header>
<main>
<h1 >This is the Home Page</h1>
<h1 >This is the About Page</h1>
</main>
</body>
CodePudding user response:
There are several ways to do what you want. One of them would work like this:
// Get all elements with class nav-link
const navLinks = document.querySelectorAll('.nav-link');
// Loop through each nav-link element
navLinks.forEach(function(navlink){
// Add click event listener to each nav-link element
navlink.addEventListener('click', function(e){
// Make sure the button being clicked exists
if(e.target){
// Get all classes on the element
const classes = e.target.classList;
// Loop through the classList to identify the buttons
classes.forEach(function(btnClass){
// Try to split the class at -
const classNameArray = btnClass.split('-');
// Make sure at least 2 array keys exist
if(1 in classNameArray){
// Make sure the class started with 'link'
if(classNameArray[0] === 'link'){
// Target the correct element to add the class
const page = document.querySelector('.' classNameArray[1] '-page');
// Add hidden class to all pages
document.querySelectorAll('.main-content').forEach(function(element){
if(!element.classList.contains('hidden')){
element.classList.add('hidden');
}
});
// Remove hidden class from the page
if(page.classList.contains('hidden')){
page.classList.remove('hidden');
}
}
}
});
}
});
});
.hidden {
display: none;
}
<header>
<button >Home</button>
<button >About</button>
</header>
<main>
<h1 >This is the Home Page</h1>
<h1 >This is the About Page</h1>
</main>
CodePudding user response:
You should use 'Event Delegation' to select different elements in page just by one click and know which element is selected then one function need:
<style>
.hidden {
display: none;
}
</style>
<body>
<header>
<button id="btn-home" >Home</button>
<button id="btn-about" >About</button>
</header>
<main>
<h1 >This is the Home Page</h1>
<h1 >This is the About Page</h1>
</main>
<script>
const navLink = document.querySelectorAll('.nav-link');
const linkHome = document.querySelector('.link-home');
const linkAbout = document.querySelector('.link-about');
const mainContent = document.querySelectorAll('.main-content');
const homePage = document.querySelector('.home-page');
const aboutPage = document.querySelector('.about-page');
function handler (event) {
if (event.target.textContent === 'Home') {
homePage.classList.remove('hidden');
aboutPage.classList.add('hidden');
}else if (event.target.textContent === 'About') {
aboutPage.classList.remove('hidden');
homePage.classList.add('hidden');
}
}
document.body.addEventListener('click', handler);
</script>
</body>