最近2个月的项目中实现的一个左右滑动菜单效果

演示地址:http://www.myliwu.com/xzwBlog/accordian/demo.html

策划最初的需求是显示8个栏目模块,默认是第一个栏目模块展开介绍文字,随后点击哪个就展开,然后其他的栏目模块处于关闭状态。

自然,就这个需求而言,是相当之简单。祭起强大无比的jquery三下五除二就搞定之。后来想了想就这样搞定也太没意义了,不光扩展性不好而且没得到锻炼。所以自己又加了几个需求:1. 整个菜单模块宽度不定死,随实际项目最外层宽度来自适应;2. 菜单内的模块数目不确定,可以是目前项目要求的8个,也可以是任意个(数目取决于整个菜单模块的最大宽度);3. 可以自定义初始状态下显示第n个栏目,而并不一定都是第一个展开。暂时,我就只想到这3个扩展需求,其他的非常规的需求有空再琢磨。

这个模块写完后感到有点不足的就是,调用时需要提供的参数过多。如果在没有备注的情况下,参数多同样会导致移植性比较差(我个人认为)。但写得过程中实在是没想到好办法精简参数,可能是我太笨了吧,那就索性把注释写详细点免得以后自己都看糊涂。

多说无用!小儿,上代码!

先上Html结构代码,大体让您勒知道今儿吃啥

1 <div class="xzwRow" style="width:450px">
 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代码,让您勒吃得更爽快!

1 // JavaScript Document
 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,只是希望自己能变得优秀)。

演示地址:http://www.myliwu.com/xzwBlog/accordian/demo.html