今天开发后台商品分类项目时,要求用树形结构展现商品的分类结构,最深有三个层级。在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 src="/static/images/public/1.png">
</a>
2. 将本级的次级条目设置 class="tree_{$vo.id}";
<tr isload="1" class="tree_{$vo.id}" >
...
</tr>
3. 真对第四种操作情况在关闭第二级的同时关闭第三级,
可以为第三级设置 id="tree_{$vo.id}";
<tr isload="1" class="tree_{$v.id}" id="tree_{$vo.id}" >
...
</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 src="/static/images/public/1.png">
</a>
</th>
<th colspan="3">
<font>
{$vo.name} [{$vo.cn_name}]
<font >({$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}" >{:lang('删除')}</a>
</td>
</tr>
{if condition='$vo.son'} {volist name='$vo.son' id='v'}
<tr isload="1" class="tree_{$vo.id}" >
<th width="30px" align="center"></th>
<th width="30px" align="center">
<a onclick="getList({$v.id})" class="cat_{$vo.id}">
<img src="/static/images/public/1.png">
</a>
</th>
<th colspan="2">
{$v.name} [{$v.cn_name}]
<font >({$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}" >{: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}" >
<th colspan="3"></th>
<th>{$m.name} [{$m.cn_name}]
<font >({$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}" >{: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 src="/static/images/public/1.png">');
_tr.hide();
__tr.hide();
}
}
总结:
其中我感到有处神来之笔就是在关闭顶级时将下级的图标初始化到折叠状态: $(".cat_" + id).html('<img src="/static/images/public/1.png">');
。通过这个案例使用ID关联自己下级的操作,并且可以让自己的代码功能实现的更优雅,真的是一个不错的选择;本案例也就只限三级,如果更深层级的扩展大家可以沿着这个方向进行扩展!