需要做一個選擇分類工具,大致要求如下:
點擊按鈕,顯示一級分類,指向某個一級分類顯示對應二級分類,分類有幾層不定。
只能選擇最后一個分類,然后把分類的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>