为了账号安全,请及时绑定邮箱和手机立即绑定

JS操作三级树形结构展开与折叠

今天开发后台商品分类项目时,要求用树形结构展现商品的分类结构,最深有三个层级。在HTML文档设计上使用Table结构,每个分类项目放在一个Tr中,二级、三级标记相对上级进行缩进;在视觉上产生分级的效果;在图标文件上绑定点击事件getList并传入该分类的ID。

根据视图事件操作分为四种类型:

 1. 展开第一级时,显示第二级条目;
 2. 展开第二级时,显示第三级条目;
 3. 关闭第二级时,隐藏第三级条目;
 4. 关闭第一级时,隐藏第二级、第三级条目;

将1、2、3、4共同点提取出来就是:在对本级进行折叠、展开操作时。相应的次级条目就会产生相应的显隐变化。于是可以在HTML文档的渲染中可以按照这样的规律渲染树形结构:

 1. 在本级的折叠/展开图标上绑定事件并将本级的ID传入;
    <a onclick="getList({$vo.id})" class="cat_{$vo.id}">
        <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/static/images/public/1.png">
    </a>
 2. 将本级的次级条目设置 class="tree_{$vo.id}";
    <tr isload="1" class="tree_{$vo.id}" style="display: none;">
        ...
    </tr>
 3. 真对第四种操作情况在关闭第二级的同时关闭第三级,
    可以为第三级设置 id="tree_{$vo.id}";
    <tr isload="1" class="tree_{$v.id}" id="tree_{$vo.id}" style="display: none;">
        ...
    </tr>

图片描述

图片描述

HTML:

<table class="display table table-striped dataTable" id="dynamic-table">
    <thead>
        <th colspan="4">{:lang('分类名称')}</th>
        <th colspan="5">{:lang('翻译状态')}</th>
        <th colspan="3">{:lang('操作')}</th>
    </thead>
    <tbody>
        {volist name='data' id='vo'}
        <tr isload="1" data-row="{$vo.id}">
            <th width="30px" align="center">
                <a onclick="getList({$vo.id})" class="cat_{$vo.id}">
                                    <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/static/images/public/1.png">
                                </a>
            </th>
            <th colspan="3">
                <font>
                    {$vo.name} [{$vo.cn_name}]
                    <font style="color:red">({$vo.id})</font>
                </font>
            </th>
            <td colspan="5" align="center">
                <font class="_lang {if condition='$vo.translate.7 eq 1'} active{/if}">FR</font>
                <font class="_lang {if condition='$vo.translate.5 eq 1'} active{/if}">DE</font>
                <font class="_lang {if condition='$vo.translate.0 eq 1'}active{/if}">EN</font>
                <font class="_lang {if condition='$vo.translate.10 eq 1'}active{/if}">JP</font>
                <font class="_lang {if condition='$vo.translate.4 eq 1'}active{/if}">KO</font>
                <font class="_lang {if condition='$vo.translate.1 eq 1'}active{/if}">CN</font>
                <font class="_lang {if condition='$vo.translate.6 eq 1'}active{/if}">AR</font>
                <font class="_lang {if condition='$vo.translate.2 eq 1'}active{/if}">IT</font>
                <font class="_lang {if condition='$vo.translate.3 eq 1'}active{/if}">PO</font>
                <font class="_lang {if condition='$vo.translate.8 eq 1'}active{/if}">SP</font>
                <font class="_lang {if condition='$vo.translate.9 eq 1'}active{/if}">RU</font>
            </td>
            <td colspan="3" align="center">
                <a class="label label-sm btn-success js-edite" id="{$vo.id}" href="javascript:;">{:lang('编辑')}</a>
                <a class="label label-sm btn-success js-add-child" id="{$vo.id}" data-level="2" href="javascript:;">{:lang('添加二级分类')}</a>
                <a class="label label-sm btn-danger js-del" id="{$vo.id}" style="cursor:pointer">{:lang('删除')}</a>
            </td>
        </tr>
        {if condition='$vo.son'} {volist name='$vo.son' id='v'}
        <tr isload="1" class="tree_{$vo.id}" style="display: none;">
            <th width="30px" align="center"></th>
            <th width="30px" align="center">
                <a onclick="getList({$v.id})" style="cursor:pointer" class="cat_{$vo.id}">
                                    <img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/static/images/public/1.png">
                                </a>
            </th>
            <th colspan="2">
                {$v.name} [{$v.cn_name}]
                <font style="color:red">({$v.id})</font>
            </th>
            <td colspan="5" align="center">
                <font class="_lang {if condition='$v.translate.7 eq 1'} active{/if}">FR</font>
                <font class="_lang {if condition='$v.translate.5 eq 1'} active{/if}">DE</font>
                <font class="_lang {if condition='$v.translate.0 eq 1'}active{/if}">EN</font>
                <font class="_lang {if condition='$v.translate.10 eq 1'}active{/if}">JP</font>
                <font class="_lang {if condition='$v.translate.4 eq 1'}active{/if}">KO</font>
                <font class="_lang {if condition='$v.translate.1 eq 1'}active{/if}">CN</font>
                <font class="_lang {if condition='$v.translate.6 eq 1'}active{/if}">AR</font>
                <font class="_lang {if condition='$v.translate.2 eq 1'}active{/if}">IT</font>
                <font class="_lang {if condition='$v.translate.3 eq 1'}active{/if}">PO</font>
                <font class="_lang {if condition='$v.translate.8 eq 1'}active{/if}">SP</font>
                <font class="_lang {if condition='$v.translate.9 eq 1'}active{/if}">RU</font>
            </td>
            <td colspan="3" align="center">
                <a class="label label-sm btn-success js-edite" id="{$v.id}" href="javascript:;">{:lang('编辑')}</a>
                <a class="label label-sm btn-success js-add-child" id="{$v.id}" data-level="3" href="javascript:;">{:lang('添加三级分类')}</a>
                <a class="label label-sm btn-danger js-del" id="{$v.id}" style="cursor:pointer">{:lang('删除')}</a>
            </td>
        </tr>
        {if condition='$v.son' id='m'} {volist name='$v.son' id='m'}
        <tr isload="1" class="tree_{$v.id}" id="tree_{$vo.id}" style="display: none;">
            <th colspan="3"></th>
            <th>{$m.name} [{$m.cn_name}]
                <font style="color:red">({$m.id})</font>
            </th>
            <td colspan="5" align="center">
                <font class="_lang {if condition='$m.translate.7 eq 1'} active{/if}">FR</font>
                <font class="_lang {if condition='$m.translate.5 eq 1'} active{/if}">DE</font>
                <font class="_lang {if condition='$m.translate.0 eq 1'}active{/if}">EN</font>
                <font class="_lang {if condition='$m.translate.10 eq 1'}active{/if}">JP</font>
                <font class="_lang {if condition='$m.translate.4 eq 1'}active{/if}">KO</font>
                <font class="_lang {if condition='$m.translate.1 eq 1'}active{/if}">CN</font>
                <font class="_lang {if condition='$m.translate.6 eq 1'}active{/if}">AR</font>
                <font class="_lang {if condition='$m.translate.2 eq 1'}active{/if}">IT</font>
                <font class="_lang {if condition='$m.translate.3 eq 1'}active{/if}">PO</font>
                <font class="_lang {if condition='$m.translate.8 eq 1'}active{/if}">SP</font>
                <font class="_lang {if condition='$m.translate.9 eq 1'}active{/if}">RU</font>
            </td>
            <td colspan="3" align="center">
                <a class="label label-sm btn-success js-edite" id="{$m.id}" href="javascript:;">{:lang('编辑')}</a>
                <a class="label label-sm btn-danger js-del" id="{$m.id}" style="cursor:pointer">{:lang('删除')}</a>
            </td>
        </tr>
        {/volist} {/if} {/volist} {/if} {/volist}
    </tbody>
</table>

JS:

//折叠、展开子分类 
function getList(id) {
    var _img = event.target,
        _icon = $(".cat_" + id),
        _tr = $('tr[class="tree_' + id + '"]'),
        __tr = $('tr[id^="tree_' + id + '"]');

    if (_tr.is(':hidden')) {
        _img.src = _img.src.replace(/\/1/, '/2');
        _tr.show();
    } else {
        _img.src = _img.src.replace(/\/2/, '/1');
        _icon.html('<img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/static/images/public/1.png">');
        _tr.hide();
        __tr.hide();
    }
}

总结:
其中我感到有处神来之笔就是在关闭顶级时将下级的图标初始化到折叠状态: $(".cat_" + id).html('<img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="/static/images/public/1.png">');。通过这个案例使用ID关联自己下级的操作,并且可以让自己的代码功能实现的更优雅,真的是一个不错的选择;本案例也就只限三级,如果更深层级的扩展大家可以沿着这个方向进行扩展!

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消