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>
时间: 2024-11-05 22:12:10

JS分类选择插件的相关文章

js 颜色选择插件

COLPICK是一款非常的轻小,无需图片就可以实现颜色选择器的jquery插件,只用 JS 和 CSS 就实现了全部功能,而且非常直观,类似Photoshop的界面,使用方便.颜色的明暗很容易自定义,整个整个都是用html5+ CSS3实现外观而,插件只有28 KB,浏览器加载速度可以说是非常快的,而在低于IE9的版本也可以使用,只需载入了支持html5的html5shiv.js. 下载该插件和 colpick.js 和 colpick.css 添加到您的文档的头: 1 <script src=

4个好用的JS联动选择插件

jQuery City Select 一个简单的jQuery省市联动插件,可以自定义JSON字典实现其他内容的联动选择菜单. PCAS省.市.地区联动选择JS封装类 PCAS可能是国内使用人数最多的JS省市联动菜单封装类,也是使用方法最简单的省市联动菜单.不过作者已经很久没更新过地址库的数据了. jQuery Dependent Selects jQuery Dependent Selects只需要在option中指明各层级之间的依赖关系,就可以自动生成多级联动下拉菜单.在小型的项目里是个不错的

原生js日期时间插件鼠标点击文本框弹出日期时间表格选择日期时间

原文出处 (这是我从互联网上搜来的,感觉能满足各方面的需求.个人感觉挺不错的,所以后期修改了一下向大家推荐!) 效果图: html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org

#JS 中国省市选择插件

中国省市选择插件  ChineseCities 1.原生JS,不依赖jquery,zepto 2.前端学习交流群:739574382 下载地址 https://github.com/chaorenzeng/ChineseCities 快速使用 1.引用 ChineseCities.min.js 2.拷贝以下布局结构 <select id="province"> <option value="请选择城市">请选择省份</option>

联动城市选择插件

index.html <!DOCTYPE html><html lang="en"> <head>    <meta charset="UTF-8">    <title>kuCity</title>    <link rel="stylesheet" href="kuCity.css">    <style>    .search

mobiscroll日期选择插件移动端插件文本选择插件

移动端选择插件mobiscroll的使用demo 一开始是弄个日期选择的插件,网上看到这个mobiscroll这个插件,然后各种下各种找demo,最后自己研究了一天下面把自己项目的demo拔出来分享给大家(以及文件下载),多多海涵,如果大家看了我的这文章有更好的写法还望赐教~ 首先是常用的日期使用: HTML部分: <li id="birthday"> <div class="mbase-menu-title">生日</div>

日期时间范围选择插件:daterangepicker使用总结

---恢复内容开始--- 分享说明: 项目中要使用日期时间范围选择对数据进行筛选;精确到年月日 时分秒;起初,使用了layui的时间日期选择插件;但是在IIE8第一次点击会报设置格式错误;研究了很久没解决,但能确定不是layui的问题;因为自己写的demo可以在IE8运行;只是在我的项目环境下某些代码冲突了;所以换用了bootstrap插件daterangepicker;看了很多资料;结合官网了文档;基本算是搞定了;把我的总结代码分享给大家;希望对使用daterangepicker插件的初学者有

JS鼠标滚动插件scrollpath使用介绍

JS鼠标滚动插件scrollpath:在这个插件中首先要引人的JS是jQuery,因为后面的JS都是基于它的.再者需要引入的是jquery.scrollpath.js.scrollpath.css还有你自己的JS和CSS. prefixfree.min.js和jquery.easing.js可以根据实际情况自己选择. 首先编写好HTML,在一个绝对定位块中分别布好每个块的位置 然后开始根据位置用JS画路径. 定义路径: $.fn.scrollPath("getPath") .moveT

js 语法高亮插件之 Prism.js

之前也介绍过几款语法高亮插件<为博客园选择一个小巧霸气的语法高亮插件>以及关于他们的综合性能<再议 语法高亮插件的选择>.今天在小影志博客看到<使用 Prism.js 实现漂亮的代码语法高亮>于是心血来潮去看了下,顺便测试了下性能.打开 Prism.js 官网,看到 Used By..我勒个去,来头不小啊. 然后看了下例子,果然思路不错,非常有意思的一个插件,于是乎我就下载到本地进行 jQuery 高亮渲染测试.测试方法和以前一样,为了和之前的插件对比,当然我的电脑也没