一直想弄清楚windows注册表里面的那个树用js怎么搞出来,昨天倒腾了一天,终于小有成就,实现了一棵拥有基本功能的js树。
以前看树感觉最复杂的部分就是那些各种线条,各种加号减号到底怎么组织出来的,用css又怎么画出一棵树来。昨天看了司徒正妹的博客,有了一些灵感,然后就试着自己摆弄了一下。
司徒用的是纯div的形式,而我用的dl列表的形式。用dl有个好处,就是即使没有样式,也能将就看,而且在语义化上也更说得过去。
好了,废话到此,下面就看怎么样一步步实现的吧
首先我们来试着画一棵静态树,我们把树分为文件夹和文件,文件夹的图标和名字放到dt里,文件夹的内容放到dd里,如果文件夹里还有子文件夹,那么子文件也是一个dl,以此类推
然后是加号减号、文件左边的虚线、左边的细线:
加号减号就是图片,但是要注意的是不同位置的加号减号四周的虚线是不一样的,一共有四种情况:
第一种:在一棵树的跟节点上,且这个根节点没有兄弟节点
第二种:在一棵树的根节点上,且这个根节点还有兄弟节点
第三种:在一棵树的分支节点上,前面后面均有兄弟节点
第四种:在一棵树的末尾分支上,只有前面有兄弟节点
文件左边的虚线只有两种情况:
第一种:非最后一个文件
第二种:最后一个文件
最后是列表左边的那天长长的竖线,这条竖线的实现其实很简单,给dl设置一个背景,然后repeat:repeat-y即可,不过只有非末尾节点才有这条线(因为这条线就是连接各个节点的线):
有了这些基本图标,我们就可以试着画一颗树了:
注意我给dl元素添加的open和close的样式,这两个样式可以用来控制文件夹的展开和收起。
随后的工作就是想办法用js来生成这些html代码了,为了使用方便,我们数据源的格式使用json,json里的对象或者数组代表文件夹,其他代表文件。这样递归循环这个json,最后把整棵树的html代码生成好,然后添加到容器里面。
在递归过程中,我们需要检测节点的位置,从而得到相应的节点图标,这个其实不难,最后我们把这个位置信息放到dl节点的自定义属性tree-position里,方便在展开和收起树的时候通过这个属性得到相应的图标。
最后我们给树的外层容器添加click方法,click后根据父节点的className来判断是收起还是展开树。
这样,一棵完整的树就生成了。如果需要链接,直接把json的属性值改为html字符串就行。