Как правильно настроить действие кнопок во вновь создаваемых div? - PullRequest
0 голосов
/ 25 марта 2019

Я пытаюсь правильно настроить действие в своем проекте списка посещаемости. Я имею в виду две кнопки с кнопкой проверки класса и кнопку времени (кнопка со значком X).

Это должно работать таким образом, когда я нажму, например, на кнопку-флажок, тогда для этой кнопки будет установлен класс «выбранный». На следующем шаге, если я нажму на кнопку времени, то кнопка-флажок должна быть отменена сама, и класс «выбран» должен быть установлен на кнопку времени и наоборот.

Чтобы продемонстрировать свою концепцию, я создал две простые кнопки со всем механизмом.

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>

В списке посещаемости я написал почти аналогичный алгоритм, но с элементами DOM

 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');
                }
            }
        }
    }
});  

и на этом фото результаты

Я не знаю, как решить эту проблему. Может быть, эта проблема вызвана множеством вложенных элементов, динамически генерируемых в документе? Может быть, кто-нибудь знает лучший способ решить эту проблему?

Ссылка на весь проект

1 Ответ

0 голосов
/ 25 марта 2019

Я объединил ваши отдельные блоки if в блоки if / else. Я думаю, что это исправило некоторые незначительные проблемы, которые были отделены от вашего вопроса.

Эта проблема, которую я вижу, является вашей внутренней проверкой if(e.target.closest('/* OTHER BUTTON'S CLASS */') !== null)

На самом деле это никогда не будет правдой. В вашем упрощенном демонстрационном примере ваш код работает, потому что вы находите все кнопки соответствующего класса и удаляете из них классы. Это очевидно не будет работать в вашем проекте, так как каждая строка должна влиять только на кнопки в этой строке (я полагаю). Вы пытаетесь найти родственника кнопки, которую вы нажали. Поэтому мы можем использовать некоторые запросы querySelector для родительского элемента нажатой кнопки, чтобы найти братьев и сестер и удалить класс.

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');
                }
            }
        }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...