JQuery制作的滑动菜单
最近2个月的项目中实现的一个左右滑动菜单效果
演示地址:http://www.myliwu.com/xzwBlog/accordian/demo.html
策划最初的需求是显示8个栏目模块,默认是第一个栏目模块展开介绍文字,随后点击哪个就展开,然后其他的栏目模块处于关闭状态。
自然,就这个需求而言,是相当之简单。祭起强大无比的jquery三下五除二就搞定之。后来想了想就这样搞定也太没意义了,不光扩展性不好而且没得到锻炼。所以自己又加了几个需求:1. 整个菜单模块宽度不定死,随实际项目最外层宽度来自适应;2. 菜单内的模块数目不确定,可以是目前项目要求的8个,也可以是任意个(数目取决于整个菜单模块的最大宽度);3. 可以自定义初始状态下显示第n个栏目,而并不一定都是第一个展开。暂时,我就只想到这3个扩展需求,其他的非常规的需求有空再琢磨。
这个模块写完后感到有点不足的就是,调用时需要提供的参数过多。如果在没有备注的情况下,参数多同样会导致移植性比较差(我个人认为)。但写得过程中实在是没想到好办法精简参数,可能是我太笨了吧,那就索性把注释写详细点免得以后自己都看糊涂。
多说无用!小儿,上代码!
先上Html结构代码,大体让您勒知道今儿吃啥
2 <div class="supportSer">
3 <h2><span class="f14">配套服务</span></h2>
4 <div class="sSer">
5 <div class="sSerBox">
6 <div id="sSerTxt2" class="txt">
7 <div class="overflowWidth">
8 <div class="sSerModel">
9 <h3>功能培训1</h3>
10 <div class="sSerText">
11 <div class="txt2">
12 <p>实际文本区域实际文本区域实际文本区域</p>
13 </div>
14 </div>
15 </div>
16 <div class="sSerModel">
17 <h3>功能培训2</h3>
18 <div class="sSerText">
19 <div class="txt2">
20 <p>实际文本区域实际文本区域实际文本区域</p>
21 </div>
22 </div>
23 </div>
24 <div class="sSerModel">
25 <h3>功能培训3</h3>
26 <div class="sSerText">
27 <div class="txt2">
28 <p>实际文本区域实际文本区域实际文本区域</p>
29 </div>
30 </div>
31 </div>
32 </div>
33 </div>
34 </div>
35 <div class="sSerLeft"></div>
36 <div class="sSerRight"></div>
37 </div>
38 </div>
39 </div>
然后,再来jquery代码,让您勒吃得更爽快!
2 var j = jQuery.noConflict();
3
4 //参数说明:
5 //elem : 具体的栏目模块
6 //overflowDiv : 让栏目模块在一行并排显示不换行的遮罩层
7 //elemTxt : 装载文本层的父级层
8 //txtContent : 装载文本的层
9 //options.currentClass : 激活状态下样式的样式名称,可根据实际情况传入不同名字
10 //options.H3Width : 栏目标题H3的宽度
11 //options.txtCurrentWidth : 默认状态下txtContent层的宽度
12 //options.marginRight : 具体栏目模块之间的间隔空白
13 j.fn.switchTabs = function(elem,overflowDiv,elemTxt,txtContent,options){
14 var defaults = {selected:0,currentClass:"sSerHover", H3Width:28,txtCurrentWidth:12, marginRight:9};
15 var _o = j.extend({},defaults,options);
16 var _box = j(this);
17 var _divWidth = _box.width();
18 //alert(_divWidth)
19 j(this).css("width",_divWidth);
20
21 j(this).children(j(overflowDiv)).css("width",_divWidth+100);
22
23 var _elem = _box.find(elem);
24 var _elemNum = _elem.length;
25
26 //栏目模块自身宽度(最小宽度)
27 var _eMinWidth = _elem.width();
28
29 //栏目模块加上margin-right的得到的总宽度
30 var _offsetWidth = _eMinWidth + _o.marginRight;
31
32 //说明文字层的宽度:总宽度-栏目模块宽度*(n-1)- 栏目模块标题H3宽度
33 var _eMaxWidth = _divWidth - _offsetWidth*(_elemNum-1) - _o.H3Width;
34
35 //栏目激活状态下的整体宽度:栏目模块标题H3宽度+说明文字层宽度
36 var _currentWidth = _o.H3Width + _eMaxWidth;
37 var rel = "current";
38 _elem.eq(_o.selected).addClass(_o.currentClass).attr("rel",rel).css("width",_currentWidth).find(elemTxt).css({"width":_eMaxWidth}).children(txtContent).css("display","block");
39 _elem.each(function(i){
40 j(_elem[i]).click(function(){
41 if(j(this).attr("rel")=="current") return;
42 _elem.each(function(n){
43 if(j(_elem[n]).attr("rel") =="current"){
44 j(_elem[n]).removeAttr("rel");
45 j(_elem[n]).removeClass(_o.currentClass).find(txtContent).css("display","none");
46 j(_elem[n]).find(elemTxt).css("width",_o.txtCurrentWidth);
47 j(_elem[n]).animate({"width":_eMinWidth});
48 }
49 });
50 j(this).addClass(_o.currentClass);
51 j(this).attr("rel",rel);
52 j(this).animate({"width":_currentWidth},1000);
53 j(this).find(elemTxt).css({"width":_eMaxWidth});
54 j(this).find(txtContent).css("display","block");
55 });
56 });
57 };
58
59 //调用
60 j(document).ready(function(){
61 j("div#sSerTxt").switchTabs(".sSerModel",".overflowWidth",".sSerText",".txt2",{selected:0,currentClass:"sSerHover"});
62 j("div#sSerTxt2").switchTabs(".sSerModel",".overflowWidth",".sSerText",".txt2",{selected:3,currentClass:"sSerHover"});
63 });
还差道菜?CSS?这个嘛,建议大家看例子的时候用firebug搭配着吃,效果比我这里好多了。
小结:不同的DOM结构就会产生不同的程序实现方式。开发期间我前后经历了三套DOM结构,最初的那套还用到了一个table来包裹栏目标题和文本层,html很冗长,js也跟着很恶心,搞得后来我自己都看不下去了。所以说,在目前的前端开发工作中,html结构的规划也占有相当重要的地位。好的Html结构促使好的程序实现(我可没夸自己写得很优秀T_T,只是希望自己能变得优秀)。