【问题标题】:Nested checkboxes not working with more than one main option嵌套复选框不适用于多个主要选项
【发布时间】:2017-10-26 14:54:35
【问题描述】:

我已使用以下codepen snippet 在我的 HTML 页面中实现嵌套复选框。原始代码仅适用于一组嵌套复选框,因此我尝试扩展到多个。但是,在这种情况下,它似乎适用于最后一个 Main 元素 Main2,但不适用于之前的。

function loadExpandableCheckboxes() {
	
	var expandableCheckboxes = document.getElementsByClassName("expandable-checkbox");
	for (var i = 0; i < expandableCheckboxes.length; i++) {
		
		var checkboxMainOption = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-main-option")[0];
		
		var checkboxSubOptions = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-sub-option");
		for (var j = 0; j < checkboxSubOptions.length; j++) {
			
			checkboxSubOptions[j].onclick = function() {
				
				var checkedCount = 0;
				for (var k = 0; k < checkboxSubOptions.length; k++) {
					if (checkboxSubOptions[k].checked) {
						checkedCount++;
					}
				}
				
				checkboxMainOption.checked = checkedCount > 0;
				checkboxMainOption.indeterminate = checkedCount > 0 && checkedCount < checkboxSubOptions.length;
			}
		}
		
		checkboxMainOption.onclick = function() {
			
			for (var j = 0; j < checkboxSubOptions.length; j++) {
				checkboxSubOptions[j].checked = checkboxMainOption.checked;
			}
		}
	}
}
onload=loadExpandableCheckboxes;
body {
  color: #555;
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}

ul {
  list-style: none;
}

li {
  margin-top: 1em;
}

label {
  font-weight: bold;
}
<html>
  <head>
	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
  </head>
  <body>
    <div class="checkbox-container">
      <ul>
        <li>
		  <div class="expandable-checkbox">
            <label><input type="checkbox" class="expandable-checkbox-main-option">Main 1</label>
            <ul>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 1</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 2</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 3</label></li>
            </ul>
		  </div>
        </li>
        <li>
		  <div class="expandable-checkbox">
            <label><input type="checkbox" class="expandable-checkbox-main-option">Main 2</label>
            <ul>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 1</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 2</label></li>
              <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 3</label></li>
            </ul>
		  </div>
        </li>
      </ul>
    </div>
	  
  </body>
</html>

【问题讨论】:

    标签: javascript jquery html css checkbox


    【解决方案1】:

    这很有趣。所以基本上要停止用第二组覆盖第一组复选框,您需要使用临时范围来保留变量。在下面的 sn-p 中,您会看到我在您的 i 循环中添加了一个 IFFE

    这样做是获取变量i,将其传递给立即调用自身的临时函数。下次循环运行时,会“创建”一个新的临时函数,从而保留最后一个函数的范围,并且不会覆盖之前的复选框集。

    $(document).ready(function() {
      //find the wrappers
      var expandableCheckboxes = document.getElementsByClassName("expandable-checkbox");
      //loop through the wrappers, count them one by one
      for (var i = 0; i < expandableCheckboxes.length; i++) (function(i){
      
        //find the the main
        var checkboxMainOption = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-main-option")[0];
        //find the subs
        var checkboxSubOptions = expandableCheckboxes[i].getElementsByClassName("expandable-checkbox-sub-option");
        //loop through subs
        for (var k = 0; k < checkboxSubOptions.length; k++) {
          
          //add listener fo each sub
          checkboxSubOptions[k].onclick = function() {
            var checkedCount = 0;
            for (var j = 0; j < checkboxSubOptions.length; j++) {
              if (checkboxSubOptions[j].checked) {
                checkedCount++;
              }
            }
            //mark appropriately
            checkboxMainOption.checked = checkedCount > 0;
            checkboxMainOption.indeterminate = checkedCount > 0 && checkedCount < checkboxSubOptions.length;
          }
        }
        //add listener to main
        checkboxMainOption.onclick = function() {
          for (var j = 0; j < checkboxSubOptions.length; j++) {
            checkboxSubOptions[j].checked = checkboxMainOption.checked;
          }
        }
      })(i)
    });
    body {
      color: #555;
      font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
    }
    
    ul {
      list-style: none;
    }
    
    li {
      margin-top: 1em;
    }
    
    label {
      font-weight: bold;
    }
    <html>
    
    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
    </head>
    
    <body>
      <div class="checkbox-container">
        <ul>
          <li>
            <div class="expandable-checkbox">
              <label><input type="checkbox" class="expandable-checkbox-main-option">Main 1</label>
              <ul>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 1</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 2</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 3</label></li>
              </ul>
            </div>
          </li>
          <li>
            <div class="expandable-checkbox">
              <label><input type="checkbox" class="expandable-checkbox-main-option">Main 2</label>
              <ul>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 1</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 2</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 3</label></li>
              </ul>
            </div>
          </li>
        </ul>
      </div>
    
    </body>
    
    </html>

    【讨论】:

      【解决方案2】:

      如果你不介意使用 JQuery,你可以在这里缩短你的 JS。试试下面的 sn-p:

      $(document).ready(function() {
        $('.expandable-checkbox-main-option').change(function() {
          $(this).parent().parent('div').find('.expandable-checkbox-sub-option').prop('checked', $(this).prop('checked'));
        });
      
        $('.expandable-checkbox-sub-option').change(function() {
          var parentCheckboxDiv = $(this).parent().parent().parent().parent('div');
          var parentCheckbox = parentCheckboxDiv.find('.expandable-checkbox-main-option');
          var checkedSubOptions = parentCheckboxDiv.find('.expandable-checkbox-sub-option:checked');
          var subOptions = parentCheckboxDiv.find('.expandable-checkbox-sub-option');
      
          parentCheckbox.prop('indeterminate', checkedSubOptions.length && checkedSubOptions.length != subOptions.length);
          parentCheckbox.prop('checked', checkedSubOptions.length == subOptions.length)
        });
      });
      body {
        color: #555;
        font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
      }
      
      ul {
        list-style: none;
      }
      
      li {
        margin-top: 1em;
      }
      
      label {
        font-weight: bold;
      }
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      
      <div class="checkbox-container">
        <ul>
          <li>
            <div class="expandable-checkbox">
              <label><input type="checkbox" class="expandable-checkbox-main-option">Main 1</label>
              <ul>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 1</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 2</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 1 Sub 3</label></li>
              </ul>
            </div>
          </li>
          <li>
            <div class="expandable-checkbox">
              <label><input type="checkbox" class="expandable-checkbox-main-option">Main 2</label>
              <ul>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 1</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 2</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 2 Sub 3</label></li>
              </ul>
            </div>
          </li>
          <li>
            <div class="expandable-checkbox">
              <label><input type="checkbox" class="expandable-checkbox-main-option">Main 3 (5 options)</label>
              <ul>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 1</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 2</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 3</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 4</label></li>
                <li><label><input type="checkbox" class="expandable-checkbox-sub-option">Main 3 Sub 5</label></li>
              </ul>
            </div>
          </li>
        </ul>
      </div>

      【讨论】:

      • 这是其中的一部分,但是当我单击子复选框时它不起作用
      • 我明白了 - 我已经更新了我的答案。这就是你要找的东西吗?
      • 我再次更新了它,以防您想将它与任意数量的子复选框(不仅仅是 3 个)一起使用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 2013-07-12
      • 1970-01-01
      相关资源
      最近更新 更多