За последние 24 часа нас посетили 22695 программистов и 1266 роботов. Сейчас ищут 823 программиста ...

Открытие и закрытие элеметов

Тема в разделе "JavaScript и AJAX", создана пользователем Dimon2x, 29 сен 2019.

  1. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Всё сам.

    Сделал код, полностью работает, можно ли как то его улучшить?

    Говнокод или пойдёт?

    Если убрать closeAnswer то остальные открытые элементы не будут сами закрываться, а будет закрываться только тот элемент, на который кликну.

    Можно потыкать https://plnkr.co/edit/Tkp3xcf8T0nKYh8ykgvC?p


    HTML:
    1. <!DOCTYPE html>
    2.  
    3.   <head>
    4.     <link rel="stylesheet" href="style.css">
    5.     <script src="script.js"></script>
    6.   </head>
    7.  
    8.   <body>
    9.  
    10.  
    11. <div class="box-question">
    12.     <div class="question">
    13.         <div class="additionally">
    14.             <a href="#">Показать ответ 1</a>
    15.         </div>
    16.     </div>
    17.  
    18.     <div class="answer answer-index">
    19.           Этот текст открывается и закрывается
    20.     </div>
    21. </div>
    22.  
    23. <div class="box-question">
    24.     <div class="question">
    25.         <div class="additionally">
    26.             <a href="#">Показать ответ 2</a>
    27.         </div>
    28.     </div>
    29.  
    30.     <div class="answer answer-index">
    31.           Этот текст открывается и закрывается
    32.     </div>
    33. </div>
    34.  
    35. <div class="box-question">
    36.     <div class="question">
    37.         <div class="additionally">
    38.             <a href="#">Показать ответ 3</a>
    39.         </div>
    40.     </div>
    41.  
    42.     <div class="answer answer-index">
    43.           Этот текст открывается и закрывается
    44.     </div>
    45. </div>
    46.  
    47.  
    48.   </body>
    49.  
    50. </html>
    Код (Javascript):
    1. function closeAnswer() {
    2.         var allAnswers = document.querySelectorAll('.answer');
    3.  
    4.         allAnswers.forEach(function (answer, i) {
    5.             answer.classList.add('answer-index');
    6.         })
    7.     }
    8.  
    9.  
    10.     document.documentElement.addEventListener('click', function (event) {
    11.         event.preventDefault();
    12.  
    13.         var target = event.target;
    14.         var question = target.closest('.box-question');
    15.         var answer = question.querySelector('.answer');
    16.  
    17.  
    18.         if (answer.classList.contains('answer-index')) {
    19.             closeAnswer()
    20.             answer.classList.remove('answer-index');
    21.         } else {
    22.             closeAnswer()
    23.             answer.classList.add('answer-index');
    24.         }
    25.  
    26.     });
    Код (CSS):
    1. .answer-index {
    2.     display: none;
    3. }
     
  2. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Код (Javascript):
    1. classList.toggle()
     
  3. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @villiwalla а что можно сделать с closeAnswer()?
     
  4. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Вообще удали и рендери с бэке
     
  5. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
  6. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Вот так сделал

    Код (Javascript):
    1. <script>
    2.  
    3.  
    4.     function closeAnswer() {
    5.         var allAnswers = document.querySelectorAll('.answer');
    6.  
    7.         allAnswers.forEach(function (answer, i) {
    8.             answer.classList.add('answer-index');
    9.         })
    10.     }
    11.  
    12.  
    13.     document.documentElement.addEventListener('click', function (event) {
    14.  
    15.         var target = event.target;
    16.  
    17.  
    18.         if (target.classList.contains("button-answer")) {
    19.             var question = target.closest('.box-question');
    20.             var answer = question.querySelector('.answer');
    21.  
    22.             if (answer.classList.contains('answer-index')) {
    23.                 closeAnswer()
    24.                 answer.classList.toggle('answer-index');
    25.             } else {
    26.                 answer.classList.toggle('answer-index');
    27.             }
    28.         }
    29.  
    30.  
    31.  
    32.     });
    33.  
    34. </script>
     
  7. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
    @Dimon2x
    Код (Javascript):
    1. let ansver = null;
    2. document.onclick = function(event)
    3. {
    4.   let target = event.target.parentElement.parentElement.parentElement.lastElementChild;
    5.  
    6.   if(target && target.classList.contains("answer"))
    7.   {
    8.     if(ansver)
    9.     {
    10.         ansver.classList.toggle("answer-index");
    11.     }
    12.  
    13.     target.classList.toggle("answer-index");
    14.     ansver = target;
    15.   }
    16. }
    похоже на говнокод, но это из за верстки
     
  8. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    @Artur_hopf
    HTML:
    1. event.target.parentElement.parentElement.parentElement.lastElementChild;
    Вставить элемент между элементами и всё сломается, надо делать привязку, к конкретным блокам.
     
  9. brevis

    brevis Активный пользователь

    С нами с:
    23 июл 2019
    Сообщения:
    69
    Симпатии:
    20
  10. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Тебе ещё учит и учить события.
    toggle принимает второй аргумент
     
  11. Artur_hopf

    Artur_hopf Активный пользователь

    С нами с:
    7 май 2018
    Сообщения:
    2.266
    Симпатии:
    405
  12. Dimon2x

    Dimon2x Старожил

    С нами с:
    26 фев 2012
    Сообщения:
    2.199
    Симпатии:
    184
    Не люблю, когда CSS используют не по назвачению
     
  13. villiwalla

    villiwalla Активный пользователь

    С нами с:
    14 дек 2016
    Сообщения:
    471
    Симпатии:
    70
    Код (Javascript):
    1. document.querySelectorAll(“.box-question”).forEach(question => question.addEventListener(“click”, questionToggle););
    2.  
    3. function questionToggle(e) {
    4. e.preventDefault();
    5.  
    6. let answer = e.currentTarget.querySelector(“.answer);
    7.  
    8. if (answer && e.target.tagName === “A”) {
    9.   answer.classList.toggle(“answer-index”, answer.classList.contains(“answer-index”);
    10. }
    11.  
    12. }
    или же вообще обойтись без forEach если выше вопросы находятся в одном контейнере
     
    Dimon2x нравится это.