简体   繁体   中英

How to set properly action of buttons in a newly generated divs?

I'm trying to set properly action in my attendance list project. I mean about two buttons with class check-button and times-button (the button with X icon).

It should work in that way when I'll click, for example on check-button, then the class 'selected' will be set on this button. In the next step if I'll click on times-button, then check-button should be deselected itself, and the class 'selected' should be set on times-button and the other way the same.

In order to demonstrate my conception, I created two simple buttons with the whole mechanism.

 let checkBtn = null; let timesBtn = null; checkBtn = document.querySelector('.check-btn'); timesBtn = document.querySelector('.times-btn'); checkBtn.addEventListener('click', function(){ if(this.classList.contains('selected')===true){ this.classList.remove('selected'); if(timesBtn.classList.contains('selected')===false){ timesBtn.classList.add('selected'); } } else if(this.classList.contains('selected')===false){ this.classList.add('selected'); if(timesBtn.classList.contains('selected')===true){ timesBtn.classList.remove('selected'); } } }); timesBtn.addEventListener('click', function(){ if(this.classList.contains('selected')===true){ this.classList.remove('selected'); if(checkBtn.classList.contains('selected')===false){ checkBtn.classList.add('selected'); } } else if(this.classList.contains('selected')===false){ this.classList.add('selected'); if(checkBtn.classList.contains('selected')===true){ checkBtn.classList.remove('selected'); } } }); 
 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Page Title</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> .check-btn.selected{ background-color: red; } .times-btn.selected{ background-color: red; } </style> </head> <body> <div class="container"> <div class="container-buttos"> <button class="check-btn">click 1</button> <button class="times-btn">click 2</button> </div> </div> </body> <script src="main.js"></script> </html> 

In the attendance list, I wrote almost similarly algorithm, but with DOM elements

 containerPerson.addEventListener('click', function(e){
    //check button
    if(e.target.closest('.check-button') !== null){ 
        if(e.target.closest('.check-button').classList.contains('selected')===true){ //start
            e.target.closest('.check-button').classList.remove('selected');
            e.target.closest('.check-button').childNodes[0].classList.remove('selected');
            if(e.target.closest('.times-button') !== null){
                if((e.target.closest('.times-button').classList.contains('selected')===false)){
                    e.target.closest('.times-button').classList.add('selected');
                    e.target.closest('.times-button ').childNodes[0].classList.add('selected');
                }
            } 
        }
    }

    if(e.target.closest('.check-button') !== null){ 
        if(e.target.closest('.check-button').classList.contains('selected')===false){ //start
            e.target.closest('.check-button').classList.add('selected');
            e.target.closest('.check-button').childNodes[0].classList.add('selected');
            if(e.target.closest('.times-button') !== null){
                if((e.target.closest('.times-button').classList.contains('selected')===true)){
                    e.target.closest('.times-button').classList.remove('selected');
                    e.target.closest('.times-button ').childNodes[0].classList.remove('selected');
                }
            }
        }
    }

    //X button
   if(e.target.closest('.times-button') !== null){ 
        if(e.target.closest('.times-button').classList.contains('selected')===true){ //start
            e.target.closest('.times-button').classList.remove('selected');
            e.target.closest('.times-button').childNodes[0].classList.remove('selected');
            if(e.target.closest('.check-button') !== null){
                if((e.target.closest('.check-button').classList.contains('selected')===false)){
                    e.target.closest('.check-button').classList.add('selected');
                    e.target.closest('.check-button').childNodes[0].classList.add('selected');
                }
            }
        }
    }
    if(e.target.closest('.times-button') !== null){ //if you haven't "e.target.closest('.times-button') !== null" then will show error: "cannot read property classList of null"
        if(e.target.closest('.times-button').classList.contains('selected')===false){ //start
            e.target.closest('.times-button').classList.add('selected');
            e.target.closest('.times-button').childNodes[0].classList.add('selected');
            if(e.target.closest('.check-button') !== null){
                if((e.target.closest('.check-button').classList.contains('selected')===true)){
                    e.target.closest('.check-button').classList.remove('selected');
                    e.target.closest('.check-button').childNodes[0].classList.remove('selected');
                }
            }
        }
    }
});  

and in this photo are the results

I don't know how to solve this problem. Maybe this problem is caused by numerously nested elements, dynamically generated in the document? Maybe someone knows a better way to solve that?

Link to the entire project

I combined your separate if blocks into if/else blocks. I think this fixed some minor issues that were separate from your question.

This issue I can see is your inner check for if(e.target.closest('/* OTHER BUTTON'S CLASS */') !== null)

This won't actually ever be true. In your simplified demo example your code works because you find all buttons of the appropriate class and remove classes from them. This obviously won't work in your project since each row should only affect the buttons in that row (I assume). You are trying to look for the sibling of the button you clicked. So we can use some querySelector calls on the parent of the clicked button to find the siblings and remove the class.

containerPerson.addEventListener('click', function(e){
        //check button
        if(e.target.closest('.check-button') !== null) { 
            e.target.closest('.check-button').classList.toggle('selected');
            e.target.closest('.check-button').childNodes[0].classList.toggle('selected');
            let sibs = e.target.closest('.check-button').parentNode.querySelector('.times-button');
            if(sibs !== null){
                if(sibs.classList.contains('selected')){
                  sibs.classList.remove('selected');
                  sibs.childNodes[0].classList.remove('selected');
                } else {
                  //sibs.classList.add('selected');
                  //sibs.childNodes[0].classList.add('selected');
                }
            }
        } else if (e.target.closest('.times-button') !== null) { 
            e.target.closest('.times-button').classList.toggle('selected');
            e.target.closest('.times-button').childNodes[0].classList.toggle('selected');
            let sibs = e.target.closest('.times-button').parentNode.querySelector('.check-button');
            if(sibs !== null){
                if(sibs.classList.contains('selected')){
                  sibs.classList.remove('selected');
                  sibs.childNodes[0].classList.remove('selected');

                } else {
                  //sibs.classList.add('selected');
                  //sibs.childNodes[0].classList.add('selected');
                }
            }
        }
});

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