JS分类选择插件

需要做一个选择分类工具,大致要求如下:

  点击按钮,显示一级分类,指向某个一级分类显示对应二级分类,分类有几层不定。

     只能选择最后一个分类,然后把分类的ID 传值给按钮的value

我的思路:

1.后台传过来的值是json,结构如下:

var json = [
  {"name":"衣服" , "id" : "1" , "pid" : 0},
  {"name":"裤子" , "id" : "2" , "pid" : 1}

];

pid是父类的ID,pid为0代表1级分类

2.根据json建立dom树,css样式很简单等会看最后的代码,结构如下:

<ul>
  <li>
    <span>衣服</span>
    <ul>
      <li><span title="1">衬衣</span></li>
      <li><span title="2">毛衣</span></li>
      <li><span title="3">内衣</span></li>
    </ul>
  </li>

</ul>

3.查询是否有下级分类,如果没有可以点击,点击后复制给按钮;否则绑定显示下级分类的hover事件

 

写了一下午,代码量大,头也晕,写得也确实不容易读。想要查看,直接复制以下代码,无图片,无外带JS,不是歪货功能OK。

<!doctype html>
<html>
<head>
<title>分类选择器</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<style>
.box{margin-top:300px;margin-left:300px;}
#btn{width:50px;height:25px;float:left}
#classifyTree{float:left;position:relative;display:none;}
#classifyTree ul{position:absolute;left:100%;top:0;border:1px solid #333;margin:0;padding:0;display:none}
#classifyTree li{float:left;list-style-type:none;position:relative;}
#classifyTree li:hover{background:#999}
#classifyTree span{float:left;display:block;height:20px;white-space:nowrap}
</style>
</head>

<body>
<div class="box" id="box">
      <input type="button" id="btn" value=""/>
    <div id="classifyTree">
       <!--
       html结构将会如下
        <ul>
            <li>
                <span>衣服</span>
                <ul>
                    <li><span title="1">衬衣</span></li>
                    <li><span title="2">毛衣</span></li>
                    <li><span title="3">内衣</span></li>
                </ul>
            </li>
            <li>
                <span>裤子</span>
                <ul>
                    <li><span>内裤</span></li>
                    <li><span>长裤</span></li>
                    <li><span>短裤</span></li>
                </ul>
            </li>
            <li>
                <span>鞋子</span>
                <ul>
                    <li><span>皮鞋</span></li>
                    <li><span>布鞋</span></li>
                    <li><span>草鞋</span></li>
                </ul>
            </li>
        </ul>-->
    </div>
</div>
</body>
<script type="text/javascript">    
    //pid代表父ID,0代表根
    var json = [
        {"name":"衣服" , "id" : "1" , "pid" : 0},
        {"name":"裤子" , "id" : "2" , "pid" : 0},
        {"name":"鞋子" , "id" : "3" , "pid" : 0},
        
        {"name":"衬衣" , "id" : "4" , "pid" : 1},
        {"name":"毛衣" , "id" : "5" , "pid" : 1},
        {"name":"内衣" , "id" : "6" , "pid" : 1},
        
        {"name":"大" , "id" : "10" , "pid" : 6},
        {"name":"大" , "id" : "11" , "pid" : 7},
        {"name":"大" , "id" : "7" , "pid" : 4},
        {"name":"中" , "id" : "8" , "pid" : 4},
        {"name":"小" , "id" : "9" , "pid" : 4}
    ];//IE下 最后一个数组不能给逗号,否则会多算一条
    

    var classifySelect = {
        treeRoot : document.getElementById("classifyTree"),//dom树根
        btn : document.getElementById("btn"),
        json : this.json,
        rootId : 0,//一级分类ID
        
        //根据json建立dom树
        setDomTree : function(){
            function creatEl(name){return document.createElement(name);}//创建标签
            var ul = creatEl("ul");
            //先建立根节点
            for(var i=0;i<this.json.length;i++){
                if(this.json[i].pid==this.rootId){
                    var li =  creatEl("li");
                    var span = creatEl("span");
                    span.title = this.json[i].id;
                    span.innerHTML = this.json[i].name;
                    li.appendChild(span);
                    ul.appendChild(li);
                    this.json.splice(i,1);//已经载入页面删除当前数组        
                    i--;//数组删除,下次循环继续查询当前位置
                }
            }                                                    
            this.treeRoot.appendChild(ul);
        
            this.addNodes(this.treeRoot.getElementsByTagName("ul")[0]);//获取插入的根ul,再查询是否有子类
        },
        
        //查询是否还有子分类,有则添加
        addNodes : function(pUl){//parent ul
            function creatEl(name){return document.createElement(name);}//创建标签
            var li = pUl.getElementsByTagName("li");
            /*
            遍历li。特别注意:由于下个for循环条件满足添加了子类后,pUl(也就是根ul)中便添加了li,li.length会改变。
            新添加的li永远在当前指针节点之后,所以不会冲突或者遗漏,而且能够在此循环结束后完成整个dom树
            */
            for(var i=0;i<li.length;i++){
                var pid = parseInt(li[i].getElementsByTagName("span")[0].title);//根据span的title存储的ID,查找json队列里是否还有子类//alert(typeof(pid));
                var ul = creatEl("ul");
                var isExist = false;//是否存在子类
                for(var j=0;j<this.json.length;j++){//遍历json,
                    if(this.json[j].pid == pid){//pid相同,添加节点到pUl
                        var newLi =  creatEl("li");
                        var newSpan = creatEl("span");
                        newSpan.title = this.json[j].id;
                        newSpan.innerHTML = this.json[j].name;
                        newLi.appendChild(newSpan);
                        ul.appendChild(newLi);
                        this.json.splice(j,1);
                        j--;
                        isExist = true;
                    }
                }
                if(isExist){
                    li[i].appendChild(ul);
                }
            }
        },
        
        
        //查找分类
        seekClassify : function(){
            var self = this;
            //点击触发分类显示
            this.btn.onclick = function(){
                self.treeRoot.style.display = "block";
                self.nextClassify(self.treeRoot,"block");//显示根分类                                                                
            }
        },
        
        //绑定事件,隐藏和显示下级分类
        bindHover : function(){
            var self = this;
            var li = self.treeRoot.getElementsByTagName("li");//获取所有li
            //绑定根
            var root =self.treeRoot.getElementsByTagName("ul")[0];
            root.onmouseover= function(){
                self.nextClassify(self.treeRoot,"block");
            }
            root.onmouseout = function(){
                self.nextClassify(self.treeRoot,"none");
            }
            for(var i=0;i<li.length;i++){
                li[i].onmouseover = function(){
                    if(self.isNextClassify(this)){
                        self.nextClassify(this,"block");
                    }
                }
                li[i].onmouseout = function(){
                    if(self.isNextClassify(this)){
                        self.nextClassify(this,"none");
                    }
                }
            }
        },
        
        //显示或者隐藏下级分类
        nextClassify : function(self,status){            
            var ul = self.getElementsByTagName("ul")[0];
            ul.style.display = status;        
        },
        
        //检查是否有下级分类,如果没有可以选择
        isNextClassify : function(li){
            var self = this;
            if(li.getElementsByTagName("ul")[0]){
                return true;
            }else{
                li.getElementsByTagName("span")[0].onclick = function(){//绑定选择事件
                    self.btn.value = this.title;
                    self.nextClassify(self.treeRoot,"none");//选择完毕隐藏
                }
                return false;
            }
        },
        
        init : function(){
            this.setDomTree();
            this.seekClassify();
            this.bindHover();        
        }
    }
    
    classifySelect.init();
</script>
</html>

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。