在线效果预览:http://jsfiddle.net/dtdxrk/JTBvg/3/embedded/result/(需要加载3m左右的png 会慢点要等等)
文件打包下载:http://files.cnblogs.com/dtdxrk/fixed-Js.rar
由于一些原因今年没有时间去香山撒野了,心里又痒痒.不能这么平淡的过冬,于是整了辆死飞玩,正好练练技术.
看到fixedchina有个配色的flash不错,正好巩固一下基础复刻一个Js版的练练手.
页面截图:
第一步 制作菜单
菜单一共有4级,我采用json格式单独引用.(我手写的,手写数据吭爹啊)
js引用地址:http://files.cnblogs.com/dtdxrk/fixed.js
第二步 加载菜单
数据写完后,我们把它加载出来.
html采用的是li里嵌套ul,这是跟WordPress学的.
这样做的好处就是可以用:hover伪类,搞定2级3级4级的show or hidden,不需要再写js.
当然ie6这个奇葩除外,我这里没有针对ie6做特殊处理...
那js要做的工作就简单多了,几个for循环把内容遍历出来就ok.
html部分结构:
1 <ul id="menu"> 2 <li>前叉 3 <ul> 4 <li>弯前叉 5 <ul> 6 <li>电镀银</li> 7 <li>阳极黑</li> 8 </ul> 9 </li> 10 <li>直前叉 11 <ul> 12 <li>黑色</li> 13 <li>白色</li> 14 </ul> 15 </li> 16 </ul> 17 </li> 18 </ul>
css部分
1 #menu{z-index: 100;left:20px; top: 20px; position:absolute;} 2 #menu ul{z-index: 101;} 3 #menu ul ul{z-index: 102;} 4 #menu ul ul ul{z-index: 103;} 5 #menu li{ width: 80px; padding-left:3px;padding-right: 2px; height: 17px;cursor: default; margin-bottom: 2px; position: relative; background: url(images/menu.gif) no-repeat;} 6 #menu li:hover, #menu li:hover a,#menu a:focus, #menu a:hover, #menu a:active {background-position: 0 -17px;} 7 #menu ul {position:absolute;display:none;width:12em;left: 85px;top: 0;z-index: 1;} 8 #menu li:hover ul ul, #menu li:hover ul ul ul, #menu li:hover ul ul ul ul{display:none;} 9 #menu li:hover ul, #menu li li:hover ul, #menu li li li:hover ul, #menu li li li li:hover ul{display:block;}
js部分
1 var doc = document, 2 ul = doc.getElementById('menu'); 3 4 //加载菜单 5 for(var i=0, length=fixedgear.length; i<length; i++){ 6 var li = doc.createElement("li"); 7 li.innerText = fixedgear[i].name; 8 9 // 2级 10 if(fixedgear[i].classes){ 11 var ul2 = doc.createElement("ul"); 12 for(var ii=0, length2=fixedgear[i].classes.length; ii<length2; ii++){ 13 var li2 = doc.createElement("li"), 14 str = fixedgear[i].classes[ii]; 15 li2.innerText = str.name; 16 17 // 3级 18 if(str.classes){ 19 var ul3 = doc.createElement("ul"); 20 for (var iii=0, length3= str.classes.length; iii<length3; iii++){ 21 var li3 = doc.createElement("li"), 22 str2 = str.classes[iii]; 23 li3.innerText = str2.name; 24 25 // 4级 26 if(str2.classes){ 27 var ul4 = doc.createElement("ul"); 28 for (var iiii=0, length4=str2.classes.length; iiii<length4; iiii++){ 29 var li4 = doc.createElement("li"); 30 str3 = str2.classes[iiii]; 31 li4.innerText = str3.name; 32 ul4.appendChild(li4); 33 } 34 li3.appendChild(ul4); 35 } 36 37 ul3.appendChild(li3); 38 } 39 li2.appendChild(ul3); 40 } 41 ul2.appendChild(li2); 42 43 } 44 li.appendChild(ul2); 45 } 46 47 ul.appendChild(li); 48 }
第三步 分解自行车在组装
之所以搞个fixed gear玩就是因为它简单.
整车从上到下只有19个零件,连刹车都没有...
当然只是零件少就简单有点肤浅了,我理解的fixed gear更多是生活方式上的简单和*.
fixed gear的后轴和飞轮是一起旋转的,你往前骑前走,往后蹬后走,一般出现在场地竞技比赛和一些特技自行车上.
置于这玩意怎么停住,就不是这里讨论的话题了...有兴趣的可以搜一下视频 fixed gear skid.
言规正传,刚才说整车有19个零件,我们就要把这些零件做成漂浮的div.
然后在给这些div添加样式设置 位置 宽 高和背景png.
来个图片更直观点 这是dreamweaver设计模式的截图 很清楚了吧
css部分
1 #chejia{width: 386px; height: 250px; background: url(images/chejia.png) no-repeat;z-index: 3;top:154px;left:187px;} 2 #lunzu, #lunzu2{width: 260px; height: 260px; background: url(images/lunzu.png) no-repeat;z-index: 2;top:245px;left:488px;} 3 #lunzu2{top:245px;left:66px;} 4 #waitai, #waitai2{width: 272px; height: 273px; background: url(images/waitai.png) no-repeat;z-index: 2;top:240px;left:482px;} 5 #waitai2{top:240px;left:60px;} 6 #lt{width: 230px; height: 88px; background: url(images/lt.png) no-repeat;z-index: 4;top:359px;left:182px;} 7 #qiancha{width: 66px; height: 143px; background: url(images/qiancha.png) no-repeat;z-index: 4;top:235px;left:558px;} 8 #wanzu{width: 40px; height: 93px; background: url(images/wanzu.png) no-repeat;z-index: 4;top:147px;left:535px;} 9 #yapan{width: 98px; height: 93px; background: url(images/yapan.png) no-repeat;z-index: 4;top:364px;left:325px;} 10 #bali{width: 59px; height: 28px; background: url(images/bali.png) no-repeat;z-index: 4;top:122px;left:530px;} 11 #zuogan{width: 45px; height: 71px; background: url(images/zuogan.png) no-repeat;z-index: 4;top:90px;left:259px;} 12 #chezuo{width: 120px; height: 32px; background: url(images/chezuo.png) no-repeat;z-index: 4;top:60px;left:215px;} 13 #wanba{width: 96px; height: 113px; background: url(images/wanba.png) no-repeat;z-index: 3;top:109px;left:563px;} 14 #jiaota{width: 61px; height: 70px; background: url(images/jiaota.png) no-repeat;z-index: 4;top:445px;left:383px;} 15 #jiaota2{width: 40px; height: 47px; background: url(images/jiaota2.png) no-repeat;z-index: 1;top:329px;left:280px;}
html部分
1 <div id="content"> 2 <ul id="menu"></ul> 3 <div id="chejia"></div> 4 <div id='lunzu'></div> 5 <div id='lunzu2'></div> 6 <div id="waitai"></div> 7 <div id="waitai2"></div> 8 <div id="lt"></div> 9 <div id="qiancha"></div> 10 <div id="wanzu"></div> 11 <div id="yapan"></div> 12 <div id="bali"></div> 13 <div id="zuogan"></div> 14 <div id="chezuo"></div> 15 <div id="wanba"></div> 16 <div id="jiaota"></div> 17 <div id="jiaota2"></div> 18 </div>
第四步 添加事件 & CSS Sprites
有了结构和数据,我们就把他们链接在一起.
点击颜色或零件的时候加载对应的背景图片
1 //如果有这个属性就给他添加点击事件 2 if(str.div) addEvent(li2, "click", loadPic(str.div, str.x, str.y)); 3 4 function addEvent(elem, type, fn){ 5 if (elem.attachEvent) { 6 elem.attachEvent('on' + type, fn); 7 return; 8 } 9 if (elem.addEventListener) { 10 elem.addEventListener(type, fn, false); 11 } 12 } 13 14 function loadPic(div, x, y){ 15 return function(){ 16 var ele = document.getElementById(div); 17 ele.style.backgroundPositionX = x + "px"; 18 ele.style.backgroundPositionY = y + "px"; 19 } 20 }
制作CSS Sprites需要拼接图片,我这里没有把所有零件都扔一张图里.
虽然这样做能减少线程,但我觉得不利于产品的后期维护.(当然这产品也不存在什么后期维护)
页面到这里就做完了,大家帮我一起测测.
用ff在jsfiddle.net在线预览时,点击菜单是没有响应的.应该是jsfiddle.net的页面框架问题,本地文件除了ie6以外所以浏览器通过测试.
这里有个问题,透明png的锯齿在flash里是可以用一个滤镜消除的.
但是在浏览器里不知道怎么搞定,我想搜搜外国的大佬们是怎么做的,可是google什么都打不开,baidu又tm啥都搜不到...
如果哪位大神有解决方案请赐教,谢谢!
全部页面:
1 <!DOCTYPE html> 2 <html lang="zh-CN"> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 <title>fixed</title> 6 <script src="fixed.js" type="text/javascript"></script> 7 <style type="text/css"> 8 *{margin: 0;padding: 0;list-style: none;} 9 body{background: #333;font:12px '微软雅黑', arial, \5b8b\4f53, sans-serif;} 10 11 h1{width: 800px;margin: 10px auto; padding:0 10px;background: #fff; line-height: 80px; height: 80px;} 12 h1 a{float:right;font-size: 16px;color: #ff007f;text-decoration: none;} 13 h1 a:hover{text-decoration: underline;} 14 15 #content{background:#fff url(images/bg.jpg) no-repeat 10px 10px;padding: 10px; width: 800px; height:550px;margin: 0 auto; position: relative; color: #333;} 16 #content div{position:absolute;} 17 18 #chejia{width: 386px; height: 250px; background: url(images/chejia.png) no-repeat;z-index: 3;top:154px;left:187px;} 19 #lunzu, #lunzu2{width: 260px; height: 260px; background: url(images/lunzu.png) no-repeat;z-index: 2;top:245px;left:488px;} 20 #lunzu2{top:245px;left:66px;} 21 #waitai, #waitai2{width: 272px; height: 273px; background: url(images/waitai.png) no-repeat;z-index: 2;top:240px;left:482px;} 22 #waitai2{top:240px;left:60px;} 23 #lt{width: 230px; height: 88px; background: url(images/lt.png) no-repeat;z-index: 4;top:359px;left:182px;} 24 #qiancha{width: 66px; height: 143px; background: url(images/qiancha.png) no-repeat;z-index: 4;top:235px;left:558px;} 25 #wanzu{width: 40px; height: 93px; background: url(images/wanzu.png) no-repeat;z-index: 4;top:147px;left:535px;} 26 #yapan{width: 98px; height: 93px; background: url(images/yapan.png) no-repeat;z-index: 4;top:364px;left:325px;} 27 #bali{width: 59px; height: 28px; background: url(images/bali.png) no-repeat;z-index: 4;top:122px;left:530px;} 28 #zuogan{width: 45px; height: 71px; background: url(images/zuogan.png) no-repeat;z-index: 4;top:90px;left:259px;} 29 #chezuo{width: 120px; height: 32px; background: url(images/chezuo.png) no-repeat;z-index: 4;top:60px;left:215px;} 30 #wanba{width: 96px; height: 113px; background: url(images/wanba.png) no-repeat;z-index: 3;top:109px;left:563px;} 31 #jiaota{width: 61px; height: 70px; background: url(images/jiaota.png) no-repeat;z-index: 4;top:445px;left:383px;} 32 #jiaota2{width: 40px; height: 47px; background: url(images/jiaota2.png) no-repeat;z-index: 1;top:329px;left:280px;} 33 34 #menu{z-index: 100;left:20px; top: 20px; position:absolute;} 35 #menu ul{z-index: 101;} 36 #menu ul ul{z-index: 102;} 37 #menu ul ul ul{z-index: 103;} 38 #menu li{ width: 80px; padding-left:3px;padding-right: 2px; height: 17px;cursor: default; margin-bottom: 2px; position: relative; background: url(images/menu.gif) no-repeat;} 39 /*#menu a {display:block;padding:14px 25px 15px;color: #fff;border-bottom: 0;font-size: 0.95em;} 40 #menu a:hover{ _border-bottom: 0;} 41 #menu li li a {padding:0.75em 25px;border: 1px dotted #d1d1d1;_background-color:#fff;_color:#000;}*/ 42 #menu li:hover, #menu li:hover a,#menu a:focus, #menu a:hover, #menu a:active {background-position: 0 -17px;} 43 /*#menu li li a:hover {background: #00a9da;color: #fff;}*/ 44 #menu ul {position:absolute;display:none;width:12em;left: 85px;top: 0;z-index: 1;} 45 /*#menu li ul a{width:10em;height:auto;float:left;}*/ 46 #menu li:hover ul ul, #menu li:hover ul ul ul, #menu li:hover ul ul ul ul{display:none;} 47 #menu li:hover ul, #menu li li:hover ul, #menu li li li:hover ul, #menu li li li li:hover ul{display:block;} 48 </style> 49 </head> 50 51 <body> 52 <h1><a href="http://www.cnblogs.com/dtdxrk/" target="_black">文刀日月-BLOG</a>Fixed Gear-JavaScript版</h1> 53 <div id="content"> 54 <ul id="menu"></ul> 55 <div id="chejia"></div> 56 <div id='lunzu'></div> 57 <div id='lunzu2'></div> 58 <div id="waitai"></div> 59 <div id="waitai2"></div> 60 <div id="lt"></div> 61 <div id="qiancha"></div> 62 <div id="wanzu"></div> 63 <div id="yapan"></div> 64 <div id="bali"></div> 65 <div id="zuogan"></div> 66 <div id="chezuo"></div> 67 <div id="wanba"></div> 68 <div id="jiaota"></div> 69 <div id="jiaota2"></div> 70 </div> 71 72 <script type="text/javascript"> 73 function isIE(){ //ie? 74 if (window.navigator.userAgent.toLowerCase().indexOf("msie")>=1) 75 return true; 76 else 77 return false; 78 } 79 80 if(!isIE()){ //firefox innerText define 81 HTMLElement.prototype.__defineGetter__("innerText", 82 function(){ 83 var anyString = ""; 84 var childS = this.childNodes; 85 for(var i=0; i<childS.length; i++) { 86 if(childS[i].nodeType==1) 87 //anyString += childS[i].tagName=="BR" ? "\n" : childS[i].innerText; 88 anyString += childS[i].innerText; 89 else if(childS[i].nodeType==3) 90 anyString += childS[i].nodeValue; 91 } 92 return anyString; 93 } 94 ); 95 HTMLElement.prototype.__defineSetter__("innerText", 96 function(sText){ 97 this.textContent=sText; 98 } 99 ); 100 } 101 102 var doc = document, 103 ul = doc.getElementById('menu'); 104 105 //加载菜单 106 for(var i=0, length=fixedgear.length; i<length; i++){ 107 var li = doc.createElement("li"); 108 li.innerText = fixedgear[i].name; 109 if(fixedgear[i].name == "Bug?意见!"){ 110 li.style.color = "#ff007f"; 111 addEvent(li, "click", function(){window.open(fixedgear[i-1].blog)}); 112 } 113 114 // 2级 115 if(fixedgear[i].classes){ 116 var ul2 = doc.createElement("ul"); 117 for(var ii=0, length2=fixedgear[i].classes.length; ii<length2; ii++){ 118 var li2 = doc.createElement("li"), 119 str = fixedgear[i].classes[ii]; 120 li2.innerText = str.name; 121 if(str.div) addEvent(li2, "click", loadPic(str.div, str.x, str.y)); 122 123 124 // 3级 125 if(str.classes){ 126 var ul3 = doc.createElement("ul"); 127 for (var iii=0, length3= str.classes.length; iii<length3; iii++){ 128 var li3 = doc.createElement("li"), 129 str2 = str.classes[iii]; 130 li3.innerText = str2.name; 131 if(str2.div) addEvent(li3, "click", loadPic(str2.div, str2.x, str2.y)); 132 133 // 4级 134 if(str2.classes){ 135 var ul4 = doc.createElement("ul"); 136 for (var iiii=0, length4=str2.classes.length; iiii<length4; iiii++){ 137 var li4 = doc.createElement("li"); 138 str3 = str2.classes[iiii]; 139 li4.innerText = str3.name; 140 if(str3.div) addEvent(li4, "click", loadPic(str3.div, str3.x, str3.y)); 141 ul4.appendChild(li4); 142 } 143 li3.appendChild(ul4); 144 } 145 146 ul3.appendChild(li3); 147 } 148 li2.appendChild(ul3); 149 } 150 ul2.appendChild(li2); 151 152 } 153 li.appendChild(ul2); 154 } 155 156 ul.appendChild(li); 157 } 158 159 //如果有这个属性就给他添加点击事件 160 if(str.div) addEvent(li2, "click", loadPic(str.div, str.x, str.y)); 161 162 function addEvent(elem, type, fn){ 163 if (elem.attachEvent) { 164 elem.attachEvent('on' + type, fn); 165 return; 166 } 167 if (elem.addEventListener) { 168 elem.addEventListener(type, fn, false); 169 } 170 } 171 172 function loadPic(div, x, y){ 173 return function(){ 174 var ele = document.getElementById(div); 175 // ele.style.backgroundImage = "images/" + div + ".png"; 176 ele.style.backgroundPositionX = x + "px"; 177 ele.style.backgroundPositionY = y + "px"; 178 } 179 } 180 181 </script> 182 183 </body> 184 </html>