简体   繁体   中英

Want less repetition when using javascript to change styles onclick

This code currently works, and when each div is clicked the background color and font size will change. In addition, the formatting for one of the other two divs which was already clicked will be removed. The problem is that this will end up requiring a lot of code, what I imagine is far more than is needed. I'm wondering how to repeat less. It is not such a big deal in this example, with only three divs, but my actual project will need many, many more.

I tried including multiple divs, so it would look like this;

document.querySelector(".div2, .div1").classList.remove("styles");

but that did not seem to work.

 const div1 = document.querySelector(".div1"); const div2 = document.querySelector(".div2"); const div3 = document.querySelector(".div3"); function makeBigDiv1 () { document.querySelector(".div1").classList.add("styles"); document.querySelector(".div2").classList.remove("styles"); document.querySelector(".div3").classList.remove("styles"); } div1.addEventListener("click", makeBigDiv1); function makeBigDiv2 () { document.querySelector(".div2").classList.add("styles"); document.querySelector(".div1").classList.remove("styles"); document.querySelector(".div3").classList.remove("styles"); } div2.addEventListener("click", makeBigDiv2); function makeBigDiv3 () { document.querySelector(".div3").classList.add("styles"); document.querySelector(".div1").classList.remove("styles"); document.querySelector(".div2").classList.remove("styles"); } div3.addEventListener("click", makeBigDiv3); 
 .div1 { width:500px; height:100px; border: 2px solid black; } .div2 { width:500px; height:100px; border: 2px solid black; } .div3 { width:500px; height:100px; border: 2px solid black; } .styles { font-size: 50px; background-color: grey; } 
 <div class="div1">One</div> <div class="div2">Two</div> <div class="div3">Three</div> 

Well as I mentioned the code works, but would just become prohibitively verbose I feel if applied to a large project. I'm relatively new to this and want to write DRY - don't repeat yourself - code. Thanks!

You can do this quite easily just by looping thru the divs. here is an example. There is some optimization you can do but you get the idea

 const div = document.querySelectorAll('.div'); for (var i = 0; i < div.length; i++) { div[i].addEventListener('click', function(event) { for (var j = 0; j < div.length; j++) { // remove styles class from all the div classes div[j].classList.remove("styles"); } // add styles class only to the clicked item this.classList.add("styles"); }); } 
 .styles { font-size: 50px; background-color: grey; } 
 <div class="div">One</div> <div class="div">Two</div> <div class="div">Three</div> 

this.classList.add("styles"); The this refers to the clicked item

If you want the three divs to have the shared style, you can style them all at once. You can also make a lot of your click functionality reusable. This is what I would do:

 const elements = document.querySelectorAll("div") function attachClickHandler(className) { return () => { document.querySelector(`.${className}`).classList.add('styles'); document.querySelectorAll(`div:not(.${className})`).forEach(element => { element.classList.remove('styles') }); } } elements.forEach(element => { element.addEventListener("click", attachClickHandler(element.className)) }) 
 <html> <head> <style> .div1, .div2, .div3 { width:500px; height:100px; border: 2px solid black; } .styles { font-size: 50px; background-color: grey; } </style> </head> <body> <div class="div1">One</div> <div class="div2">Two</div> <div class="div3">Three</div> <script> </script> </body> </html> 

In context you would probably not want to add event listeners to every div so you could just add a class to all divs you want to make selectable and find all by class name instead of find all of type div. This would also allow you to add the base styling for the shared class instead of to all 3 divs.

Here are some changes:

    1. Use the same className for each block, and give it a specific name (ie box ).
    1. Same for the added className, make it clear. (ie is-selected ).
    1. Don't duplicate functions for the same action and use forEach instead to loop through each box.

 // Get all boxes const boxes = document.querySelectorAll('.box'); // For each box [...boxes].forEach(box => { // Attach an event click listener box.addEventListener('click', () => { // Add the `is-selected` className to the clicked one box.classList.add('is-selected'); // Remove the `is-selected` className to all the others [...boxes].filter(el => el !== box).forEach(box => { box.classList.remove('is-selected'); }) }); }); 
 .box { width: 500px; height: 100px; border: 2px solid black; } .box.is-selected { font-size: 50px; background-color: grey; } 
 <div class="box">One</div> <div class="box">Two</div> <div class="box">Three</div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM