[Javascript][Mootools]用渐进增强的方式开发选项卡(Tabs)(二)
在这一节里,我将对在上一节完成的基础上,对Tabs类进行扩展,加上自定义事件以及动画效果。
Mootools通过类的implements属性,实现类似于接口的功能,比如我们在Tabs类的implements属性加上Events,就可以让Tabs类获得Events类下的所有方法,其中的fireEvent方法就是让Tabs类获得了自定义事件的能力。
然后我在Tabs类下的showSection方法和hideSection方法内各加上一行代码:
this.fireEvent('onShow',[index,tab,section]);
this.fireEvent('onHide',[index,tab,section]);
这样,就可以在生成一个Tabs类的实例时,加上用户自定义的事件,代码如下:
示例页中第一个例子即是,我通过自定义事件,得到当前显示隐藏的选项卡各是哪个,同时,我还给显示选项内容加上了动画效果。
虽然能通过自定义事件给选项卡加上动画效果,但是我想动画效果可能是经常需要实现的功能,因此,我对Tabs类下的showSection方法和hideSection方法进行了改写,这样,我们就可以在可选属性里设定是否通过动画来显示选项卡,而且,虽然我目前只做了一种动画,但是动画效果可以继续扩展,并通过可选属性来选择使用何种动画效果。
可选属性加上的属性是mvSH。实例代码如下:
示例页第二个例子即是最终效果。
代码如下:
按道理到这里,这节要实现的功能已经完成,不过上面的类可以通过Mootools类的implement方法,将代码改成可扩展的Tabs类来完成,而这么做的好处是,我们可以通过工作的需要来选择是简化版Tabs类,还是扩展后的Tabs类,这样做也可以在继续扩展动画效果的情况下,不需要改动原有的Tabs类。
Mootools通过类的implements属性,实现类似于接口的功能,比如我们在Tabs类的implements属性加上Events,就可以让Tabs类获得Events类下的所有方法,其中的fireEvent方法就是让Tabs类获得了自定义事件的能力。
然后我在Tabs类下的showSection方法和hideSection方法内各加上一行代码:
this.fireEvent('onShow',[index,tab,section]);
this.fireEvent('onHide',[index,tab,section]);
这样,就可以在生成一个Tabs类的实例时,加上用户自定义的事件,代码如下:
Code
1 var myTabs = new Tabs($$('#tabs li'),$$('#sections li'),{
2 onShow:function(index,tab,section){
3 $('tips_show').set('text','当前显示的是第'+(index+1)+'个内容');
4 section.setStyles({opacity:0}).fade(1);
5 },
6 onHide:function(index){
7 $('tips_hide').set('text','当前隐藏的是第'+(index+1)+'个内容');
8 }
9 });
1 var myTabs = new Tabs($$('#tabs li'),$$('#sections li'),{
2 onShow:function(index,tab,section){
3 $('tips_show').set('text','当前显示的是第'+(index+1)+'个内容');
4 section.setStyles({opacity:0}).fade(1);
5 },
6 onHide:function(index){
7 $('tips_hide').set('text','当前隐藏的是第'+(index+1)+'个内容');
8 }
9 });
示例页中第一个例子即是,我通过自定义事件,得到当前显示隐藏的选项卡各是哪个,同时,我还给显示选项内容加上了动画效果。
虽然能通过自定义事件给选项卡加上动画效果,但是我想动画效果可能是经常需要实现的功能,因此,我对Tabs类下的showSection方法和hideSection方法进行了改写,这样,我们就可以在可选属性里设定是否通过动画来显示选项卡,而且,虽然我目前只做了一种动画,但是动画效果可以继续扩展,并通过可选属性来选择使用何种动画效果。
可选属性加上的属性是mvSH。实例代码如下:
Code
1 var myTabs1 = new Tabs($$('#tabs1 li'),$$('#sections1 li'),{
2 mvSH:1,
3 selectedTabCss:'.tabOn',
4 unSelectedTabCss:'.tabOff'
5 });
1 var myTabs1 = new Tabs($$('#tabs1 li'),$$('#sections1 li'),{
2 mvSH:1,
3 selectedTabCss:'.tabOn',
4 unSelectedTabCss:'.tabOff'
5 });
示例页第二个例子即是最终效果。
代码如下:
Code
1 var Tabs = new Class({
2
3 Implements: [Options,Events],
4
5 options:{
6 selectedTabCss:'selected',
7 selectedSectionCss:'selected',
8 mvSH:0,
9 firstShow:0,
10 mouseEvent:'click'
11 },
12
13 initialize:function(tabs, sections, options){
14 this.setOptions(options);
15 this.current = this.options.firstShow;
16 this.tabs = $$(tabs);
17 this.sections = $$(sections);
18 this.sectionsLength = $$(sections).length;
19 this.attach();
20 this.render();
21 },
22
23 render:function(){
24 this.sections.each(function(section, index){
25 if( index !== this.current ) {
26 section.hide();
27 }else{
28 this.showSection(index);
29 };
30 }, this);
31 },
32
33 attach:function(){
34 this.tabs.each(function(tab, index){
35 tab.addEvent(this.options.mouseEvent,this.tabEvent.bindWithEvent(this,tab));
36 }, this);
37 },
38
39 tabEvent:function(e,tab){
40 e.preventDefault();
41 var index = this.tabs.indexOf(tab);
42 this.toggleSection(index);
43 },
44
45 toggleSection:function(index){
46 if(this.current === index) return;
47 this.hideSection(this.current);
48 this.current = index;
49 this.showSection(this.current);
50 },
51
52 showSection:function(index){
53 var tab = this.tabs[index];
54 var section = this.sections[index];
55 switch (this.options.mvSH) {
56 case 1:
57 section.setStyles({display:'block',opacity:0}).fade(1);
58 tab.morph(this.options.selectedTabCss);
59 break;
60 default:
61 tab.addClass(this.options.selectedTabCss);
62 section.addClass(this.options.selectedSectionCss).show();
63 }
64 this.fireEvent('onShow',[index,tab,section]);
65 },
66
67 hideSection:function(index){
68 if (index===false) return;
69 var tab = this.tabs[index];
70 var section = this.sections[index];
71 switch (this.options.mvSH) {
72 case 1:
73 section.hide();
74 tab.morph(this.options.unSelectedTabCss);
75 break;
76 default:
77 tab.removeClass(this.options.selectedTabCss);
78 section.removeClass(this.options.selectedSectionCss).hide();
79 }
80 this.fireEvent('onHide',[index,tab,section]);
81 }
82 });
1 var Tabs = new Class({
2
3 Implements: [Options,Events],
4
5 options:{
6 selectedTabCss:'selected',
7 selectedSectionCss:'selected',
8 mvSH:0,
9 firstShow:0,
10 mouseEvent:'click'
11 },
12
13 initialize:function(tabs, sections, options){
14 this.setOptions(options);
15 this.current = this.options.firstShow;
16 this.tabs = $$(tabs);
17 this.sections = $$(sections);
18 this.sectionsLength = $$(sections).length;
19 this.attach();
20 this.render();
21 },
22
23 render:function(){
24 this.sections.each(function(section, index){
25 if( index !== this.current ) {
26 section.hide();
27 }else{
28 this.showSection(index);
29 };
30 }, this);
31 },
32
33 attach:function(){
34 this.tabs.each(function(tab, index){
35 tab.addEvent(this.options.mouseEvent,this.tabEvent.bindWithEvent(this,tab));
36 }, this);
37 },
38
39 tabEvent:function(e,tab){
40 e.preventDefault();
41 var index = this.tabs.indexOf(tab);
42 this.toggleSection(index);
43 },
44
45 toggleSection:function(index){
46 if(this.current === index) return;
47 this.hideSection(this.current);
48 this.current = index;
49 this.showSection(this.current);
50 },
51
52 showSection:function(index){
53 var tab = this.tabs[index];
54 var section = this.sections[index];
55 switch (this.options.mvSH) {
56 case 1:
57 section.setStyles({display:'block',opacity:0}).fade(1);
58 tab.morph(this.options.selectedTabCss);
59 break;
60 default:
61 tab.addClass(this.options.selectedTabCss);
62 section.addClass(this.options.selectedSectionCss).show();
63 }
64 this.fireEvent('onShow',[index,tab,section]);
65 },
66
67 hideSection:function(index){
68 if (index===false) return;
69 var tab = this.tabs[index];
70 var section = this.sections[index];
71 switch (this.options.mvSH) {
72 case 1:
73 section.hide();
74 tab.morph(this.options.unSelectedTabCss);
75 break;
76 default:
77 tab.removeClass(this.options.selectedTabCss);
78 section.removeClass(this.options.selectedSectionCss).hide();
79 }
80 this.fireEvent('onHide',[index,tab,section]);
81 }
82 });
按道理到这里,这节要实现的功能已经完成,不过上面的类可以通过Mootools类的implement方法,将代码改成可扩展的Tabs类来完成,而这么做的好处是,我们可以通过工作的需要来选择是简化版Tabs类,还是扩展后的Tabs类,这样做也可以在继续扩展动画效果的情况下,不需要改动原有的Tabs类。
Code
1 var Tabs = new Class({
2
3 Implements:[Options,Events],
4
5 options:{
6 selectedTabCss:'selected',
7 selectedSectionCss:'selected',
8 firstShow:0,
9 mvSH:0,
10 mouseEvent:'click'
11 },
12
13 initialize:function(tabs, sections, options){
14 this.setOptions(options);
15 this.current = this.options.firstShow;
16 this.tabs = $$(tabs);
17 this.sections = $$(sections);
18 this.sectionsLength = $$(sections).length;
19 this.attach();
20 this.render();
21 },
22
23 render:function(){
24 this.sections.each(function(section, index){
25 if( index !== this.current ) {
26 section.hide();
27 }else{
28 this.showSection(index);
29 };
30 }, this);
31 },
32
33 attach:function(){
34 this.tabs.each(function(tab, index){
35 tab.addEvent(this.options.mouseEvent,this.tabEvent.bindWithEvent(this,tab));
36 }, this);
37 },
38
39 tabEvent:function(e,tab){
40 e.preventDefault();
41 var index = this.tabs.indexOf(tab);
42 this.toggleSection(index);
43 },
44
45 toggleSection:function(index){
46 if(this.current === index) return;
47 this.hideSection(this.current);
48 this.current = index;
49 this.showSection(this.current);
50 },
51
52 showSection:function(index){
53 var tab = this.tabs[index];
54 var section = this.sections[index];
55 tab.addClass(this.options.selectedTabCss);
56 section.addClass(this.options.selectedSectionCss).show();
57 this.fireEvent('onShow',[index,tab,section]);
58 },
59
60 hideSection:function(index){
61 if (index===false) return;
62 var tab = this.tabs[index];
63 var section = this.sections[index];
64 tab.removeClass(this.options.selectedTabCss);
65 section.removeClass(this.options.selectedSectionCss).hide();
66 this.fireEvent('onHide',[index,tab,section]);
67 }
68 });
69
70 Tabs.implement({
71 showSection:function(index){
72 var tab = this.tabs[index];
73 var section = this.sections[index];
74 switch (this.options.mvSH) {
75 case 1:
76 section.setStyles({display:'block',opacity:0}).fade(1);
77 tab.morph(this.options.selectedTabCss);
78 break;
79 default:
80 tab.addClass(this.options.selectedTabCss);
81 section.addClass(this.options.selectedSectionCss).show();
82 }
83 this.fireEvent('onShow',[index,tab,section]);
84 },
85
86 hideSection:function(index){
87 if (index===false) return;
88 var tab = this.tabs[index];
89 var section = this.sections[index];
90 switch (this.options.mvSH) {
91 case 1:
92 section.hide();
93 tab.morph(this.options.unSelectedTabCss);
94 break;
95 default:
96 tab.removeClass(this.options.selectedTabCss);
97 section.removeClass(this.options.selectedSectionCss).hide();
98 }
99 this.fireEvent('onHide',[index,tab,section]);
100 }
101 });
1 var Tabs = new Class({
2
3 Implements:[Options,Events],
4
5 options:{
6 selectedTabCss:'selected',
7 selectedSectionCss:'selected',
8 firstShow:0,
9 mvSH:0,
10 mouseEvent:'click'
11 },
12
13 initialize:function(tabs, sections, options){
14 this.setOptions(options);
15 this.current = this.options.firstShow;
16 this.tabs = $$(tabs);
17 this.sections = $$(sections);
18 this.sectionsLength = $$(sections).length;
19 this.attach();
20 this.render();
21 },
22
23 render:function(){
24 this.sections.each(function(section, index){
25 if( index !== this.current ) {
26 section.hide();
27 }else{
28 this.showSection(index);
29 };
30 }, this);
31 },
32
33 attach:function(){
34 this.tabs.each(function(tab, index){
35 tab.addEvent(this.options.mouseEvent,this.tabEvent.bindWithEvent(this,tab));
36 }, this);
37 },
38
39 tabEvent:function(e,tab){
40 e.preventDefault();
41 var index = this.tabs.indexOf(tab);
42 this.toggleSection(index);
43 },
44
45 toggleSection:function(index){
46 if(this.current === index) return;
47 this.hideSection(this.current);
48 this.current = index;
49 this.showSection(this.current);
50 },
51
52 showSection:function(index){
53 var tab = this.tabs[index];
54 var section = this.sections[index];
55 tab.addClass(this.options.selectedTabCss);
56 section.addClass(this.options.selectedSectionCss).show();
57 this.fireEvent('onShow',[index,tab,section]);
58 },
59
60 hideSection:function(index){
61 if (index===false) return;
62 var tab = this.tabs[index];
63 var section = this.sections[index];
64 tab.removeClass(this.options.selectedTabCss);
65 section.removeClass(this.options.selectedSectionCss).hide();
66 this.fireEvent('onHide',[index,tab,section]);
67 }
68 });
69
70 Tabs.implement({
71 showSection:function(index){
72 var tab = this.tabs[index];
73 var section = this.sections[index];
74 switch (this.options.mvSH) {
75 case 1:
76 section.setStyles({display:'block',opacity:0}).fade(1);
77 tab.morph(this.options.selectedTabCss);
78 break;
79 default:
80 tab.addClass(this.options.selectedTabCss);
81 section.addClass(this.options.selectedSectionCss).show();
82 }
83 this.fireEvent('onShow',[index,tab,section]);
84 },
85
86 hideSection:function(index){
87 if (index===false) return;
88 var tab = this.tabs[index];
89 var section = this.sections[index];
90 switch (this.options.mvSH) {
91 case 1:
92 section.hide();
93 tab.morph(this.options.unSelectedTabCss);
94 break;
95 default:
96 tab.removeClass(this.options.selectedTabCss);
97 section.removeClass(this.options.selectedSectionCss).hide();
98 }
99 this.fireEvent('onHide',[index,tab,section]);
100 }
101 });