Как показать / скрыть меню на основе значения флажка (ов) с помощью JavaScript? - PullRequest
0 голосов
/ 01 октября 2018

Обновление 10/4/18: Я обновил Фрагмент, чтобы отразить изменения для всех, кто может наткнуться на эту ветку в поисках помощи.Существующие флажки и новые добавленные флажки откроют / закроют меню.

var statusChangeMenu, activeList, itemCheckBox, activeItems;
statusChangeMenu = document.getElementById("status-change-menu");
activeList = document.getElementById("active-items");
itemCheckBox = activeList.getElementsByClassName("item-checkbox");
activeItems = activeList.getElementsByClassName("active-item-text");

function addNewItem(event) {
  event.preventDefault();
  activeList.insertAdjacentHTML("afterbegin", "\
<li class=\"item\">\
  <input class=\"item-checkbox\" type=\"checkbox\" name=\"checkbox\" />\
  <span class=\"active-item-text\"></span>\
  <button class=\"btn-complete\">complete</button>\
</li>");
  activeItems[0].textContent = document.getElementById("new-item-text").value;
}

document.getElementById("btn-add-item").addEventListener("click", addNewItem, false);
activeList.addEventListener("change", function() {
  var i, len;
  for (i = 0, len = itemCheckBox.length; i < len || (i = 0); ++i) {
    if (itemCheckBox[i].checked) {
      i = 40;
      break;
    }
  }
  statusChangeMenu.style.height = i + "px";
}, false);
*{
    margin: 0;
    padding: 0;
}
body{
    background-color: #393F4D;
}
header{
    background-color: #1D1E22;
    color: #FEDA6A;
    text-align: center;
    font-size: 10px;
}
main{
    background-color: #707070;
    max-width: 700px;
    margin: auto;
    margin-top: 20px;
    padding: 15px;
}
#status-change-menu{
    background-color: rgb(218, 123, 123);
    margin-top: 10px;
    height: 0px;
    overflow: hidden;
    transition: all .25s ease-in-out;
}
#status-change-menu>button>img{
    height: 40px;  
}
form{
    background-color: #D4D4DC;
    padding: 10px;
    text-align: right;
    box-shadow: 1px 1px 3px;
}
#new-item-text{
    width: 100%;
}
#btn-add-item{
    padding: 5px;
    box-shadow: 1px 1px 3px; 
}
.item-list-container{
    background-color: #D4D4DC;
    margin-top: 20px;
    box-shadow: 1px 1px 3px;
}
.item{
    background-color: rgb(165, 233, 222);
    list-style: none;
    display: grid;
    grid-template-columns: auto 1fr max-content;
    grid-template-rows: 30px;
    margin-top: 10px;
}
.item-checkbox{
    grid-column: 1/2; 
  width: 30px;
  margin:auto;
}
.active-item-text{
    grid-column: 2/3;
    background: rgb(252, 252, 252);
    overflow: hidden;
}
.btn-complete{
 grid-column: 3/4;
}
.item>input{
  height: 20px;
}
<body id="the-list">
    <header>
        <h1>The List V4</h1>
    </header>
    <main>
        <form action="#">
            <textarea name="textbox" id="new-item-text" cols="30" rows="1"></textarea>
            <button type="submit" id="btn-add-item">Add</button>
        </form>
        <div id="status-change-menu" class="change-menu">
          <h3>Status Change Menu</h3>
            <button class="btn-bar-hold">BTN1<img src="img/btn_hold.svg" alt=""></button>
            <button class="btn-bar-delete">BTN2<img src="img/btn_delete.svg" alt=""></button>
        </div>
        <div class="item-list-container">
            <ul id="active-items" class="item-list">
                <li class="item">
                  <input class="item-checkbox" type="checkbox" name="checkbox">
                  <span class="active-item-text">random text text random</span>
                  <button class="btn-complete">complete</button>
                </li>
                <li class="item">
                  <input class="item-checkbox" type="checkbox" name="checkbox">
                  <span class="active-item-text">random text text random</span>
                  <button class="btn-complete">complete</button>
                </li>
            </ul>
        </div>
    </main>
</body>

Я работаю над простым веб-приложением с контрольным списком, использующим чистый ванильный HTML, CSS, javascript.Я застрял в одной части все выходные.Надеясь, что кто-то может пролить свет на то, что я скучаю или делаю неправильно.Вот где я нахожусь.

Моя цель

Всякий раз, когда выбран элемент в контрольном списке (ul) (через флажок), скрытое меню выдвигается с различнымиварианты для управления выбранным элементом (ами).Меню должно оставаться видимым, если установлены какие-либо флажки в списке.Меню должно закрыться, если флажки не установлены.

Где я застрял

Я могу заставить меню выдвигаться во время события 'change' флажка, но не могу получитьэлемент меню, чтобы реагировать после начального события изменения.Во время отладки также кажется, что элемент меню не реагирует на флажок в «проверенном» состоянии, а просто реагирует на изменение флажка в целом.Вот код JS, который у меня есть, но я проверил различные другие конфигурации безуспешно.

Code Pen с полным кодом и фрагмент соответствующего кода JS ниже.Обновленный Codepen 10/4/18 https://codepen.io/skazx/pen/mzeoEO?

var itemCheckBox = document.querySelectorAll('input[type="checkbox"]')
var statusChangeMenu = document.getElementById("status-change-menu")

for(var i = 0 ; i < itemCheckBox.length; i++){
  itemCheckBox[i].addEventListener("change", function(){

    if (!itemCheckBox.checked)
    {statusChangeMenu.style.height = "40px";}
    else 
    {statusChangeMenu.style.height = "0px";}
  })}

Я прочитал несколько десятков различных постов и статей, но большинство из них были связаны только с одним флажком или использованным jquery.Дайте мне знать, если вам нужны дополнительные подробности.Спасибо!

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

mhodges правильно в том, что itemCheckBox является NodeList, а не отдельным элементом.Другая проблема заключается в том, что вы пытаетесь проверить, установлен ли измененный флажок, а если нет, вы закрываете меню.Как вы описали, это не то, что вам нужно.

Вам нужен еще один способ проверить, все ли флажки сняты, прежде чем закрыть меню.Простой способ сделать это - просто еще один внутренний цикл в функции onChange:

for(var i = 0 ; i < itemCheckBox.length; i++){
  itemCheckBox[i].addEventListener("change", function(){
    showMenu = false
    for(var j = 0; j < itemCheckBox.length; j++)
      {
        if(itemCheckBox[j].checked)
          showMenu = true
      }
    if (showMenu)
      {statusChangeMenu.style.height = "40px";} 
    else 
      {statusChangeMenu.style.height = "0px";}
})}

Вот модифицированный Фрагмент

0 голосов
/ 01 октября 2018

itemCheckBox относится к NodeList, возвращаемому querySelectorAll, а не к отдельному элементу, поэтому высказывание itemCheckBox.checked на самом деле не имеет смысла.

Вы должны проверить, установлен ли флажок any в списке, который можно использовать с функцией .some(), например:

Вот рабочая демонстрация

for (var i = 0; i < itemCheckBox.length; i++) {
  itemCheckBox[i].addEventListener("change", function(event) {
    if (!event.target.checked) {
      statusChangeMenu.style.height = "40px";
    } else {
      statusChangeMenu.style.height = "0px";
    }
  });
}

var itemCheckBox = document.querySelectorAll('input[type="checkbox"]');
var statusChangeMenu = document.getElementById("status-change-menu");
function changeHandler (event) {
  // get the list of checkboxes in real time in case any were added to the DOM
  var checkboxes = document.querySelectorAll('input[type="checkbox"]');
  var anyChecked = [].some.call(checkboxes, function(checkbox) { return checkbox.checked; });
  // alternatively (instead of using .some()):
  // var anyChecked = false;
  // checkboxes.forEach(function (checkbox) {
  //   if (checkbox.checked) {
  //     anyChecked = true;
  //   }
  // });

  if (anyChecked) {
    statusChangeMenu.style.height = "40px";
  } else {
    statusChangeMenu.style.height = "0px";
  }
}
for (var i = 0; i < itemCheckBox.length; i++) {
  itemCheckBox[i].addEventListener("change", changeHandler);
}

for (var i = itemCheckBox.length; i < itemCheckBox.length + 2; i++) {
  // add some checkboxes dynamically
  var newCheckbox = document.createElement("input");
  var newLabel = document.createElement("label");
  newLabel.innerText = "Checkbox " + (i + 1);
  newCheckbox.type = "checkbox";
  // -- IMPORTANT-- bind event listener on dynamically added checkbox
  newCheckbox.addEventListener("change", changeHandler);
  newLabel.appendChild(newCheckbox);
  newLabel.appendChild(document.createElement("br"));
  document.body.appendChild(newLabel);
}
#status-change-menu {
  height: 0;
  background-color: red;
  overflow: hidden;
  color: white;
  font-weight: bold;
}
<div id="status-change-menu">I should be visible if any checkboxes are checked</div>
<label>Checkbox 1<input type="checkbox"/></label><br/>
<label>Checkbox 2<input type="checkbox"/></label><br/>
<label>Checkbox 3<input type="checkbox"/></label><br/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...