一个简单的js树形菜单 |
本文标签:树形菜单 我练习一下,以免不时之需 。 树形菜单不过就是把普通菜单重新排列一下,看起来像树形而已 。 上图京东的菜单,给他多几个嵌套,然后添加收缩伸展事件,差不多就行了 。 给个例子: 复制代码 代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> <style type="text/css"> body{ font-size: 12px;} h2,h3{ margin: 0;} ul{ margin: 0; padding: 0; list-style: none; } #outer_wrap li{ padding-left: 30px; line-height: 24px;} .controlSymbol{ padding: 0 5px; border: 1px solid #adff2f; cursor: pointer;} </style> </head> <body> <ul id="outer_wrap"> <li> <h2>标题1</h2> <ul> <li>内容1</li> <li>内容2</li> <li>内容3</li> <li>内容4</li> <li> <h3>标题1_1</h3> <ul> <li>内容1_1</li> <li>内容1_2</li> <li>内容1_3</li> <li>内容1_4</li> </ul> </li> <li> <h3>标题1_2</h3> <ul> <li>内容1_1</li> <li>内容1_2</li> <li>内容1_3</li> <li>内容1_4</li> </ul> </li> </ul> </li> </ul> </body> </html> 然后添加事件: 复制代码 代码如下: var innerText = document.innerText ? innerText : textContent; var span = document.createElement(span); span[innerText] = -; span.className = controlSymbol; function $(id){ return document.getElementById(id); } function $_(){ var args = arguments; var ret = []; for(var i = 0; i < args.length; i++){ var temp = document.getElementsByTagName(args[i]); try{ ret = ret.concat(Array.prototype.slice.call(temp,0)); }catch(e){ for(var j = 0; j < temp.length; j++){ ret.push(temp[j]); } } } return ret; } function addSymbol(h){ var innerSpan = span.cloneNode(true); h.insertBefore(innerSpan,h.firstChild); } function next(el){ while(el.nextSibling){ if(el.nextSibling.nodeType == 1){ return el.nextSibling; } el = el.nextSibling; } return null; } var outerWrap = $(outer_wrap); var hs = $_(h2,h3); for(var i = 0 ; i < hs.length; i++){ addSymbol(hs[i]); } outerWrap.onclick = function(event){ event = event || window.event; var t = event.target || event.srcElement; if(t.className == controlSymbol){ var sn = next(t.parentNode); var snStyle = next(t.parentNode).style; snStyle.display = (snStyle.display == block || snStyle.display == ) ? none : block; t[innerText] = t[innerText] == + ? -:+; } } 不过用的多的可能是动态的添加菜单,也就是动态的生成HTML序列 。 一个例子: 复制代码 代码如下: var tree = { 标题2:[ 内容1, 内容2, 内容3, 内容4, {标题2_1:[内容2_1,内容2_2,内容2_3,内容2_4]}, {标题2_2:[内容2_1,内容2_2,内容2_3,内容2_4]}, 内容5 ] } var fragment = document.createElement(ul); function concatTree(tree){ var array = []; for(var key in tree){ array.push(<li><h3>); array.push(key); array.push(</h3><ul>); for(var i = 0; i < tree[key].length; i++){ if(tree[key][i].constructor == Object){ array = array.concat(concatTree(tree[key][i])); }else{ array.push(<li>); array.push(tree[key][i]); array.push(</li>); } } array.push(</ul></li>); } return array; } fragment.innerHTML = concatTree(tree).join(); $(outer_wrap).appendChild(fragment.firstChild); 像上面的方法也可以用来生成表格,扯远了,比如 复制代码 代码如下: var oArray = { thead : [标题一,标题二,标题三,标题四], tbody : [ [1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16], [17,18,19,20], [21,22,23,24] ], tfoot : [25,26,27,28] } function createTable(arr){ var html = []; html.push(<table>); for(var key in arr){ html.push(<+key + >); if(key == thead){ assemTag(arr[key],html,th) }else if(key == tfoot){ assemTag(arr[key],html,td) }else if(key == tbody){ for(var k = 0, len_1 = arr[key].length; k < len_1; k++){ assemTag(arr[key][k],html,td) } } html.push(</+key + >); } html.push(</table>); var temp = document.createElement(div); temp.innerHTML = html.join(); return temp.firstChild; } function assemTag(array,html,tag){ html.push(<tr>); var s = < + tag + >; var e = </ + tag + >; for(var j = 0, len = array.length; j < len; j++){ html.push(s); html.push(array[j]); html.push(e); } html.push(</tr>); } document.body.appendChild(createTable(oArray)); 一般可以直接创建一个节点元素,然后直接设置innerHTML,不过innerHTML虽说是IE先搞起的,但是IE又最不彻底,对于table和tr是不可设置innerHTML的(只读),所以只能假div之手了 。 |