javascript - jquery树遍历

标签 javascript jquery jquery-selectors

我有一个任务需要遍历树(检查/取消检查单个项目)。我已经编写了代码,它工作正常但有时速度很慢。请帮助我改进它。

这是假设的工作方式:

  1. 取消选中父取消选中 该 parent 的所有 child
  2. 取消选中(一个或多个) 子节点取消检查父节点
  3. 自动检查父级 检查它所有的 child
  4. 当所有 child 都检查过 parent 也被检查 自动地
    • 这也适用于任何深度树..所以如果有 3 级深度节点取消选中最内层的子节点将取消选中每个节点的第一个父节点。

其他一些注意事项: CSS 类:

  • "checked"- 黑色字体,移除后字体为灰色
  • “标记”- 灰色背景

所以:

  • 当 parent 没有选择 child 时,它的 css 类“选中”被删除(它变成灰色)
  • 当一个项目未被选中时,它的 css 类“选中”和“标记”被删除(黑色字体变为灰色并且没有灰色背景)
  • 当取消选中所有子级时,父级的“标记”类将被删除(灰色背景被删除)。

我希望这个插图对您有所帮助: enter image description here

及部分HTML源码:

<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:30px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Aparatura elektryczna, elektroenergetyka   </span></div>

<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:60px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Silniki, napędy, automatyka napęd&#243;w </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:90px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Silniki i napędy przemysłowe </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Prądu stałego   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Prądu przemiennego </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>synchroniczne   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>asynchroniczne </span></div>

</li></ul></li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Silniki krokowe   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Siłowniki elektryczne   </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Liniowe </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Obrotowe </span></div>
</li></ul></li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Serwosilniki, serwonapędy </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Inne </span></div>

</li></ul></li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:90px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Układy zabezpieczeń silnik&#243;w   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:90px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Elektroniczne układy sterowania napęd&#243;w   </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Przemienniki prądu stałego   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Przemienniki częstotliwości (falowniki)   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Układy łagodnego rozruchu (softstarty)   </span></div>

</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Sterowniki silnik&#243;w DC </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:120px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Sterowniki silnik&#243;w krokowych </span></div>
<ul class='treeList2b'><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Jednoosiowe   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Wieloosiowe   </span></div>
</li><li class='open'>                        <div class="tlWrap clearfix marked checked" style="padding-left:150px;"><input type="checkbox" checked="checked" class="checkbox" name="SelectedBranch" id="SelectedBranch"><span>Wieloosiowe z interpolacją   </span></div>

</li></ul></li>

...

还有我的脚本:

<script type="text/javascript">
/*<![CDATA[*/
    $(function(){           
        $('ul.treeList2b .checkbox').click(function(e){
            e.stopPropagation();
            var obj = $(this).closest('li').find(':checkbox'); 
            obj.attr('checked', this.checked);
            var childCnt=obj.size();  // get childrent count - when parent was clicked
            var checkedCnt=obj.filter(':checked').length; // out of those get those that are checked
            if (childCnt==checkedCnt){
                obj.parents('li').each(function (index, element) {
                    var objSub = $(element).find('li');
                    childCnt = objSub.size();
                    checkedCnt = objSub.find(':checkbox:checked').length;
                    if (childCnt==checkedCnt) { 
                        $(element).find(':checkbox:first').attr("checked", true);
                        $(element).children('div.tlWrap').addClass('checked');
                    }
                    $(element).children('div.tlWrap').addClass('marked');
                });
            }else{ 
                var objParent = obj.parents('li').find(':checkbox:first');
                objParent.attr("checked", false);
                objParent.parent('div.tlWrap').removeClass('checked');
            }
            refleshCheckbox(this);
        });
    });
    function refleshCheckbox(obj){
        if(!$(obj).attr('checked')){
            $(obj).closest('li').find('div.tlWrap').removeClass('marked');
        } 
        if ($(obj).closest('ul').find(':checkbox:checked').length==0){
            $(obj).closest('ul').parent().find('div.tlWrap').removeClass('marked');
        }
    }
/*]]>*/
</script>

最佳答案

我不会将所有功能添加到此答案中,因为您将通过自己实现它们来了解更多信息。但是我做了一个test case on jsFiddle如图所示:

$(".option-tree > li > label > input:checkbox").each(function(){
    var $this = $(this),
        options = $this.closest("li").find("> ul > li > label > input:checkbox");

    $this.change(function(){
        options.prop("checked", $this[0].checked);
    });

    options.change(function(){
        var  all = options.length,
           checked = options.filter(":checked").length;
        $this[0].checked = all === checked;
    });

});

注意上面的例子使用了jQuery 1.6你必须在哪里使用 .prop而不是 .attr.removeAttr .

对于早期版本的 jQuery(1.6 之前),它看起来像这样:

$(".option-tree > li > label > input:checkbox").each(function(){
    var $this = $(this),
        options = $this.closest("li").find("> ul > li > label > input:checkbox");

    $this.change(function(){
        if ($this[0].checked) {
            options.attr("checked", "checked");
        } else {
            options.removeAttr("checked");
        }
    });

    options.change(function(){
        var  all = options.length,
           checked = options.filter(":checked").length;
        $this[0].checked = all === checked;
    });

});

关于javascript - jquery树遍历,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5907142/

相关文章:

javascript - 用于一个祖先的多个元素的 JQuery 选择器

javascript - 如果选中所有子复选框,如何选中父复选框

jQuery 选择器问题。 :last-child not doing what I need

javascript - Backbone 包括在头部?

jquery - 使用 jQuery 隐藏动态元素的正确方法

javascript - 如何删除 JavaScript 初始化?

javascript - 如何在 JavaScript 中运行随机选择的函数?

javascript - 无法将字符串格式化为日期

javascript - 如何在 JavaScript 中运行序列函数

javascript - 将数据从 HTML 表单获取到 JavaScript