JS子父类复选框问题

如何做到勾选了子类的全部,父类文学自动也勾选

<input type="checkbox" name="check" value="1" class="0" onClick="DoAllSubChecked(1,this)">文学
<input type="checkbox" name="check" value="2" class="1" onClick="DoAllSubChecked(2,this)">三国
<input type="checkbox" name="check" value="3" class="1" onClick="DoAllSubChecked(3,this)">西游
<input type="checkbox" name="check" value="4" class="1" onClick="DoAllSubChecked(4,this)">红楼
<input type="checkbox" name="check" value="5" class="1" onClick="DoAllSubChecked(5,this)">水浒

clipboard.png

阅读 2.6k
4 个回答

图片描述

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Linked Checkbox</title>
    <script>
    document.addEventListener('DOMContentLoaded', function(){

        function LinkedCheckbox($domBase)
        {
            this.domBase = $domBase || document;
        }
        LinkedCheckbox.prototype.queryChildList = function($domThis, $checked, $recurse){
            let selector = 'input[type="checkbox"]';

            if($domThis === null)
                selector += '[data-path]';
            else
            {
                let thisPath     = $domThis.getAttribute('data-path');
                let thisPathDeep = parseInt($domThis.getAttribute('data-path-deep'), 10);

                selector += '[data-path^="'+(thisPath+'.')+'"]';

                if($recurse === false)
                    selector += '[data-path^="'+(thisPath+'.')+'"][data-path-deep="'+(thisPathDeep+1)+'"]';

                if($checked === true)
                    selector += ':checked';
            }

            return this.domBase.querySelectorAll(selector);
        };
        LinkedCheckbox.prototype.querySuper = function($domThis){
            let thisPath     = $domThis.getAttribute('data-path');
            let thisPathDeep = parseInt($domThis.getAttribute('data-path-deep'), 10);

            if(thisPathDeep === 1)
                return null;

            let superPath     = thisPath.substr(0, thisPath.lastIndexOf('.'));
            let superPathDeep = thisPathDeep - 1;

            return this.domBase.querySelector('input[type="checkbox"][data-path="'+(superPath)+'"][data-path-deep="'+(superPathDeep)+'"]');
        };
        LinkedCheckbox.prototype.onchange_child = function($domThis){
            let arrDomChild = this.queryChildList($domThis, false, true);
            let i;
            for(i=0; i<arrDomChild.length; i++)
            {
                arrDomChild[i].checked = $domThis.checked;
                arrDomChild[i].indeterminate = false;
            }
        };
        LinkedCheckbox.prototype.onchange_super = function($domThis){

            let domSuper = $domThis;
            let arrDomChild, arrDomChildChecked;
            while(domSuper != null)
            {
                domSuper = this.querySuper(domSuper);
                if(domSuper === null)
                    break;

                arrDomChild        = this.queryChildList(domSuper, false, true);
                arrDomChildChecked = this.queryChildList(domSuper, true, true);

                if($domThis.checked === true)
                {
                    domSuper.checked = true;
                    domSuper.indeterminate = (arrDomChildChecked.length < arrDomChild.length);
                }
                else
                {
                    if(arrDomChildChecked.length <= 0)
                    {
                        domSuper.checked = false;
                        domSuper.indeterminate = false;
                    }
                    else
                    {
                        domSuper.checked = true;
                        domSuper.indeterminate = (arrDomChildChecked.length < arrDomChild.length);
                    }
                }
            }
        };
        LinkedCheckbox.prototype.onchange = function($domThis){
            this.onchange_child($domThis);
            this.onchange_super($domThis);
        };

        (function(/* init */){
            let linkedCheckbox = new LinkedCheckbox(document);

            let arrDomCheckBox = linkedCheckbox.queryChildList(null, false, true);
            let funOnChange = function(){linkedCheckbox.onchange(this)};
            let i, dom, path;
            for(i=0; i<arrDomCheckBox.length; i++)
            {
                dom = arrDomCheckBox[i];
                path = dom.getAttribute('data-path');
                dom.setAttribute('data-path-deep', path.split('.').length);

                dom .addEventListener('change', funOnChange);
            }
        })();
    });
    </script>
</head>
<body>
<label><input type="checkbox" name="check" value="1" class="0" data-path="1">文学</label>
<br />
&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1">三国</label>
<br />
&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.1">魏</label>
<br />
&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.2">吴</label>
<br />
&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.3">蜀</label>
<br />
&emsp;&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.3.1">刘备</label>
<br />
&emsp;&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.3.2">关羽</label>
<br />
&emsp;&emsp;&emsp;<label><input type="checkbox" name="check" value="2" class="1" data-path="1.1.3.3">张飞</label>
<br />
&emsp;<label><input type="checkbox" name="check" value="3" class="1" data-path="1.2">西游</label>
<br />
&emsp;<label><input type="checkbox" name="check" value="4" class="1" data-path="1.3">红楼</label>
<br />
&emsp;<label><input type="checkbox" name="check" value="5" class="1" data-path="1.4">水浒</label>
</body>
</html>

提供我的思路:你可以将父类和子类分开,子类用一个元素包裹,父类用一个元素包裹,获取子类父元素所有子类checkbox的checked是否都为true,如果是则父类就设置checked为true,如果只有一个,则为半选,全部都是false,则checke为false。

用原生js实现了,并且写了详细备注

<body>

<div id="wrapper">
<input type="checkbox" name="check" value="1" class="check checkAll">文学
<input type="checkbox" name="check" value="2" class="check">三国
<input type="checkbox" name="check" value="3" class="check">西游
<input type="checkbox" name="check" value="4" class="check">红楼
<input type="checkbox" name="check" value="5" class="check">水浒
</div>

<script type="text/javascript">
var checkList = document.getElementsByClassName("check"); // 获取所有checkBox节点
var checkAllList = document.getElementsByClassName("checkAll"); // 获取所有全选节点(这里只有一个)
var checkBoxLenth = checkList.length;  //总个数
var checkedSize = 0; //已勾选个数

for(var i=0; i< checkBoxLenth; i++){ 
    checkList[i].onclick = function(){   // 为每一个checkBox节点都添加onClick事件
        if( this.className.indexOf("checkAll") > -1){   // 如果是全选
            for(var j=0; j< checkBoxLenth; j++ ) {
                checkList[j].checked = this.checked;  // 子选项的状态根据全选状态改变而改变
            }
        }else{
            if(!this.checked){  // 如果当前操作是取消选择,则全选checked 设为false
                for(var k = 0; k < checkAllList.length; k++ ){
                    checkAllList[k].checked = false;
                }
                checkedSize--;
            }else{
                checkedSize++;    
            }
        }
        
        if(checkedSize >= checkBoxLenth -1 ){ // 如果已勾选个数>=除开全选框的个数,则全选框勾上
            for(var k = 0; k < checkAllList.length; k++ ){
                    checkAllList[k].checked = true;
                }
        }
    }
}

</script>

</body>

后面4个子类存一个数组。
把选中的push进数组。
当数组长度等于4时,勾选第一个父类。
反选第一个父类的时候,清空数组

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
1 篇内容引用
推荐问题