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>
#classifyTree{position:absolute;left:0;top:100%;z-index:1111;display:none;}
#classifyTree ul{position:absolute;left:100%;top:0;border:1px solid #ccc;margin:0;padding:0;display:none}
#classifyTree li{float:left;list-style-type:none;position:relative;cursor:pointer}
#classifyTree span:hover{background:#09C}
#classifyTree span{float:left;display:block;width:100px;text-align:center;height:25px;white-space:nowrap;background:#f1f1f1;border-bottom:1px dashed #CCC;line-height:25px}
#cid1{visibility:hidden;}
#cid1Text{width:75px;height:25px;border-color:#CCC;border-style:solid;border-width:1px 0 1px 1px;background:#f1f1f1;cursor:pointer;line-height:25px;float:left;text-indent:5px;padding:0;ss}
.classifyBox{height:25px;cursor:pointer;display:inline-block;position:relative}
.arrowBorder{width:25px;height:25px;border-color:#CCC;border-style:solid;border-width:1px 1px 1px 0px;background:#f1f1f1;display:inline-block;float:left}
.downArrow{margin:8px 0 0 8px; width: 0;height: 0; border-left: 5px solid transparent;border-right: 5px solid transparent;border-top: 10px solid #181818;float:left}
</style>
</head>
<body>
<div class="classifyBox">
<div id="classifyClick">
<input type="text" id="cid1Text"/>
<div class="arrowBorder">
<div class="downArrow"></div>
</div>
</div>
<div id="classifyTree">
</div>
</div> <input type="text" name="category_id" value="" id="cid1"/>
</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("cid1"),
btnText : document.getElementById("cid1Text"),
btnClick : document.getElementById("classifyClick"),
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.alt = 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].alt);//根据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.alt = 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.btnClick.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.alt;
self.btnText.value = this.innerHTML;
//document.getElementById("cid2").value = self.titlePlace;//绑定到保存草稿input
self.nextClassify(self.treeRoot,"none");//选择完毕隐藏
}
return false;
}
}, init : function(){
this.setDomTree();
this.seekClassify();
this.bindHover();
}
} classifySelect.init();
</script>
</html>
JS分类选择插件的更多相关文章
- js 颜色选择插件
COLPICK是一款非常的轻小,无需图片就可以实现颜色选择器的jquery插件,只用 JS 和 CSS 就实现了全部功能,而且非常直观,类似Photoshop的界面,使用方便.颜色的明暗很容易自定义, ...
- 4个好用的JS联动选择插件
jQuery City Select 一个简单的jQuery省市联动插件,可以自定义JSON字典实现其他内容的联动选择菜单. PCAS省.市.地区联动选择JS封装类 PCAS可能是国内使用人数最多的J ...
- 【JS】一款好用的JS日历选择插件【bootstrap-datetimepicker.js】
1.插件名称:bootstrap-datetimepicker.js,下载地址:上Github下载或者下面链接 2.效果图: 3.使用方法:里面有Demo 链接: https://pan.baidu. ...
- 纯原生js移动端城市选择插件
接着上一篇纯js移动端日期选择插件,话说今天同事又来咨询省市县联动的效果在移动端中如何实现,还是老样子,百度上一搜,诶~又全是基于jquery.zepto的,更加可恨的是大多数都是PC版的,三个sel ...
- 原生js日期时间插件鼠标点击文本框弹出日期时间表格选择日期时间
原文出处 (这是我从互联网上搜来的,感觉能满足各方面的需求.个人感觉挺不错的,所以后期修改了一下向大家推荐!) 效果图: html代码: <!DOCTYPE html PUBLIC " ...
- 纯原生js移动端日期选择插件
最近在项目上需要使用日期选择插件,由于是移动端的项目,对请求资源还是蛮节约的,可是百度上一搜,诶~全是基于jquery.zepto的,本来类库就很大,特别像mobiscroll这种样式文件一大堆又丑又 ...
- 移动设备日期选择插件(基于JQUERY)
上周花了2个小时写的一个日期选择插件,比较适合移动端的设备.先看个效果图吧.如果刚好是你需要的就往下吧,不需要的也可以继续..... 其实网络上已经有的了类似的成熟插件,比如基于mobiscroll, ...
- 日期时间范围选择插件:daterangepicker使用总结
分享说明: 项目中要使用日期时间范围选择对数据进行筛选;精确到年月日 时分秒;起初,使用了layui的时间日期选择插件;但是在IIE8第一次点击会报设置格式错误;研究了很久没解决,但能确定不是layu ...
- 原生js版分页插件
之前我在自己的博客里发表了一篇用angularJs自定义指令实现的分页插件,今天简单改造了一下,改成了原生JavaScript版本的分页插件,可以自定义一些简单配置,特此记录下来.如有不足之处,欢迎指 ...
随机推荐
- 【Resharper】C# “Simplify conditional ternary expression”
#事故现场: 对某个对象做空值检测的时候,结合三元运算符给某变量赋值的时候,R#提示:"Simplify conditional ternary expression" : R#建 ...
- 如何将Azure SQL 数据库还原到本地数据库实例中
原文:https://www.jerriepelser.com/blog/restore-sql-database-localdb/ 原文作者: Jerrie Pelser 译文:如何将Azure S ...
- 三、动态SQL
动态SQL MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑. 动态SQL的元素 元素 作用 备注 if 判断语句 单条件分支判断 choose.whe ...
- 基于bert的命名实体识别,pytorch实现,支持中文/英文【源学计划】
声明:为了帮助初学者快速入门和上手,开始源学计划,即通过源代码进行学习.该计划收取少量费用,提供有质量保证的源码,以及详细的使用说明. 第一个项目是基于bert的命名实体识别(name entity ...
- 运行时报:尝试加载 Oracle 客户端库时引发 BadImageFormatException,如果在安装 32 位 Oracle 客户端组件的情况下以 64 位模式运行,将出现此问题
运行环境为: Windows Server2012 Oracle11g 32位数据库+客户端 IIS发布后提示错误信息: “尝试加载 Oracle 客户端库时引发 BadImageFormatExc ...
- vs code搭建Django环境
在网上找了很多博客,看了vs code的官方文档,最终拼凑起来,终于搭建起来了djangode开发虚拟环境(win10下) 一.新建项目文件夹 F:\Python\temp\django_demo(例 ...
- go-gtk环境配置
go-gtk环境配置(用于go的图形化界面) 弄了一天,终于把这个环境给搭建好了,差不多就是安装msys2->安装gtk的各个版本->安装mingw(我原来装有但不影响,因为重复了,环境变 ...
- CAD如何能画的快?老师傅教你5个技巧,远超他人
都知道CAD用途是很广泛,各行各业都是离不开CAD画图设计,机械,建筑,园林,服装,家具…… 画图速度一定要够快速,这样才能够满足需求,事实上会发现有的人绘图非常快速,但是你出一张图却要加班赶点.差距 ...
- 如何突破DNS报文的512字节限制
- DNS的512字节限制 根据协议标准,DNS协议同时占用UDP和TCP的53端口,这是为什么呢? 翻阅DNS资料,可以发现,DNS协议默认按UDP传输,为优化传输性能,DNS协议有一个512字节的 ...
- 962. Maximum Width Ramp
本题题意: 在数组中,找到最大的j-i,使得i<j and A[i] <= A[j] 思路: 维持一个递减的栈,遇到比栈顶小的元素,进栈: 比大于等于栈顶的元素-> 找到栈中第一个小 ...