如何使用JavaScript根据复选框的值显示/隐藏菜单?

时间:2018-10-01 19:58:25

标签: javascript for-loop if-statement checkbox

更新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开发一个简单的清单Web应用程序。我整个周末都陷入了困境。希望有人可以阐明我的缺失或做错了什么。这是我的位置。

我的目标

每当(通过复选框)选中清单(ul)中的某个项目时,一个隐藏的菜单就会滑出,带有各种选项来操纵所选的项目。如果选中了列表中的任何复选框,则菜单必须保持可见。如果未选中任何复选框,则菜单必须关闭。

我被困在哪里

在复选框的“更改”事件期间,我能够使菜单滑出,但是在初始更改事件之后,我无法使菜单元素做出反应。在调试过程中,菜单元素似乎并未对复选框处于“已检查”状态做出反应,而只是对复选框的更改做出了反应。这是我拥有的JS代码,但我已经测试了其他各种配置,但均未成功。

带有完整代码的代码笔和下面的相关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";}
  })}

我阅读了几十篇不同的文章和文章,但大多数与只有1个复选框或使用过的jquery有关。让我知道您是否需要其他详细信息。谢谢!

2 个答案:

答案 0 :(得分:2)

itemCheckBox指的是NodeList返回的querySelectorAll,而不是单个元素,因此说itemCheckBox.checked并没有任何意义。

您应该检查列表中的任何复选框是否已选中,您可以将其与.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/>

答案 1 :(得分:2)

方法正确,因为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";}
})}

这里有一个经过修改的Snippet