显示隐藏的模块化组件

模块化组件包括以下几个文件:

base.css       重置浏览器样式

jquery.js        包括本地引入 和 其他服务器引入 如:cdnjs.com中引入

transitionend.js      transitionend动画结束后执行的代码,该方法的兼容性写法,使用js进行封装

s.js                      显示隐藏的模块化组件,可以定义为下拉菜单的组件 dropdown.js ,包括三种方式:

       1, 全局变量调用:就是去掉(function(){  })() 自我执行的函数套套

       2,接口形式调用:使用window.mt = window.mt || {}; window.mt.showHide = showHide;

 

=======以下是index.html 代码:========

 

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4   <meta charset="UTF-8">
  5   <title>Document</title>
  6   <link rel="stylesheet" href="css/base.css">
  7   <style>
  8     .container {
  9       width: 500px;
 10       margin: 100px auto;
 11     }
 12     button {
 13       width: 50%;
 14       height: 50px;
 15     }
 16     .box {
 17       display: none;
 18       height: 450px;
 19       width: 500px;
 20       background: green;
 21     }
 22     .transition {
 23       -webkit-transition: all .5s;
 24       -moz-transition: all .5s;
 25       -ms-transition: all .5s;
 26       -o-transition: all .5s;
 27       transition: all .5s;
 28     }
 29     /* css3.fade的类 */
 30     .fade {
 31       opacity: 0;
 32       visibility: visible;
 33     }
 34     /* css3.slideUpDown的类 */
 35     .slideUpDown {
 36       height: 0;
 37       padding-top: 0;
 38       padding-bottom: 0;
 39     }
 40     /* css3.slideLeftRight的类 */
 41     .slideLeftRight {
 42       width: 0;
 43       padding-left: 0;
 44       padding-right: 0;
 45     }
 46     /* css3.fadeSlideUpDown的类 */
 47     .fadeSlideUpDown {
 48       opacity: 0;
 49       height: 0;
 50       padding-top: 0;
 51       padding-bottom: 0;
 52     }
 53     /* css3.fadeSlideLeftRight的类 */
 54     .fadeSlideLeftRight {
 55       opacity: 0;
 56       width: 0;
 57       padding-left: 0;
 58       padding-right: 0;
 59     }
 60 
 61   </style>
 62 </head>
 63 <body>
 64   <div class="container">
 65     <button class="show">显示</button
 66     ><button class="hide">隐藏</button>
 67     <div class="box"></div>
 68     asdfasd
 69   </div>
 70   <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
 71   <script>
 72     window.jQuery || document.write('<script src="js/jquery.js"><\/script>')
 73   </script>
 74   <!-- transitionend.js文件必须放在 index.js 上面,因为是index.js调用transitionend.js -->
 75   <script src="js/transitionend.js"></script>
 76   <script src="js/s.js"></script>
 77   <script>
 78       //获取jquery对象
 79       var $show = $('.show'),
 80           $hide = $('.hide'),
 81           $box  = $('.box');
 82 
 83 
 84           // ========方法一:========
 85           //最初的调用方法,也是最不可取的,因为变量全部都是全局变量
 86           //当s.js中的内容全部都是全局作用域的时候还可以直接调用如下:
 87           /*css3.slideUpDown.init($box);
 88           css3.fadeSlideLeftRight.init($box);
 89 
 90           //给两个按钮绑定单击事件
 91           $show.on('click',function(){
 92             css3.slideUpDown.show($box);
 93             // js.fadeSlideLeftRight.show($box);
 94           })
 95           $hide.on('click',function(){
 96             css3.slideUpDown.hide($box);
 97             // js.fadeSlideLeftRight.hide($box);
 98 
 99           })
100           //给$box对象绑定四个事件
101           $box.on('show shown hide hidden',function(e){
102             console.log(e.type)
103           })*/
104 
105 // ========方法二:========
106 //这是使用接口调用的
107 /*     var showHide = window.mt.showHide($box,{
108       css:true,
109       js:true,
110       animation:'slideLeftRight'
111      })
112       //给两个按钮绑定事件
113       $show.on('click',function(){
114         //调用show本身要带被调用对象的参数,因为定义的时候就有一个参数。
115         //但该参数在定义 showHide接口方法时就被使用$.proxy(fn,this,$box)给代理调用了,
116         //所以这里可以省略
117         showHide.show();
118       })
119       $hide.on('click',function(){
120         //调用hide本身要带被调用对象的参数,因为定义的时候就有一个参数。
121         //但该参数在定义 showHide接口方法时就被使用$.proxy(fn,this,$box)给代理调用了,
122         //所以这里可以省略
123         showHide.hide();
124       })
125       //给$box对象绑定事件
126       $box.on('show shown hide hidden',function(e){
127         console.log(e.type);
128       })*/
129 
130 // ========方法三:========  
131 // 封装成插件调用
132       var a = $box.showHide({
133         css3:true,
134         js:false,
135         animation:'slideLeftRight'
136       });
137       //返回一个对象:k.fn.init [div.box.transition.slideUpDown, prevObject: k.fn.init(1)]
138       console.log(a);
139       
140       //给两个按钮绑定单击事件
141       $show.on('click',function(){
142           $box.showHide('show');
143       });
144       $hide.on('click',function(){
145           $box.showHide('hide');
146       })
147 
148       //给$box绑定四个事件
149       $box.on('click',function(e){
150         console.log(e.type);
151       })
152   </script>
153 </body>
154 </html>

 

=======以下是base.css代码:========

 

 1 /*重置浏览器的默认样式css reset*/
 2     /*清除内外边距*/
 3     body, h1, h2, h3, h4, h5, h6, p, hr, /*结构元素*/
 4     ul, ol, li, dl, dt, dd, /*列表元素*/
 5     form, fieldset, legend, input, button, select, textarea, /*表单元素*/
 6     th, td, /*表格元素*/
 7     pre {
 8         padding: 0;
 9         margin: 0;
10     }
11 
12     /*重置默认样式*/
13     body, button, input, select, textarea {
14         /*font: 12px/1 微软雅黑, Tahoma, Helvetica, Arial, 宋体, sans-serif;*/
15         color: #333;
16         font: 12px/1 "Microsoft YaHei", Tahoma, Helvetica, Arial, SimSun, sans-serif;
17     }
18     h1, h2, h3, h4, h5, h6 {
19         font-size: 100%;
20         font-weight: normal;
21     }
22     em, i {
23         font-style: normal;
24     }
25 
26     a {
27         text-decoration: none;
28     }
29     li {
30         list-style-type: none;
31         vertical-align: top;
32     }
33     img {
34         border: none;
35         /*display: block;*/
36         vertical-align: top;
37     }
38     textarea {
39         overflow: auto;
40         resize: none;
41     }
42     table {
43         border-spacing: 0;
44         border-collapse: collapse;
45     }
46 
47 /*常用公共样式*/
48     .fl {
49         float: left;
50         display: inline;
51     }
52     .fr {
53         float: right;
54         display: inline;
55     }
56     .cf:before,
57     .cf:after {
58         content: " ";
59         display: table;
60         
61     }
62     .cf:after {
63         clear: both;
64     }
65     .cf {
66         *zoom: 1;
67     }

 

=======以下是  transitionend.js 代码:========

 

 1 /*使用js外部文件编写兼容性,以下编写的是:
 2 transitionend事件的兼容性写法:
 3 分析:
 4 1,先判断浏览器兼容什么样的过渡样式,相应的,浏览器就支持对应的过渡事件。
 5 
 6 如何操作检验浏览器是否支持transition属性对应的transitionend事件:
 7 在谷歌中检验:
 8 1,在控制台输入:document.body.style  返回:CSSStyleDeclaration...
 9 2,点开CSSStyleDeclaration...  查找关于支持transition的写法,找到如下:
10     transition
11     webkitTransition
12     对应过渡事件:
13     点击谷歌控制台的眼睛图标:
14     输入transitionend,就会出现关于过渡事件的所有写法:
15     推算下:
16     标准写法:transition         对应事件:transitionend
17     webkit写法:webkitTransition  对应事件:webkitTransitionEnd
18     除了标准写法:连缀写法应该跟样式的写法相同;上面都是使用驼峰命名规则。
19 */
20 (function(){
21 
22     //使用对象存放存放键值对数据,
23     //键:存放transition是否支持该样式,样式支持才能支持该样式对应的事件
24     //值:存放支持transition该样式对应的事件
25     var transitionEventNames = {
26         webkitTransition:'webkitTransitionEnd',//chrome
27         // MozTransition:'webkittransitionend',//firefox
28         // webkitTransition:'webkittransitionend',//opera
29         transition:'transitionend' //标准,IE要么支持标准,要么就不支持
30     };
31 
32     //存放支持transition该样式对应的事件名
33     var transitionend = '',
34         isSupport     = false;//默认不支持
35 
36         //遍历对象,判断浏览器支持对象中的那个键名,那么就支持该键对应的事件
37     for (var a in transitionEventNames) {
38         //不存在的属性返回undefined,不存在的对象直接报错。
39         if (document.body.style[a] !== undefined) {
40             transitionend = transitionEventNames[a];
41             isSupport     = true;
42 
43             //如果浏览器能支持其中一个,则直接退出,不循环了。
44             break;
45         }
46     }
47 
48 //这里面全部都是局部作用域,都是局部变量。外面不可以直接访问。
49 //创建一个全局变量对象window.mt,方便其他地方调用。
50 //1,如果该对象已经存在,则直接使用
51 //2,如果该对象不存在,则创建一个空对象{}
52     window.mt || {};
53     //给该对象两个属性
54     //name   支持transition样式对应的事件名
55     //isSupport  是否支持transition样式,默认不支持
56     //其实这里就是海外面访问的接口
57     window.mt = {
58         name:transitionend,
59         isSupport:isSupport
60     }
61 })()

 

=======以下是  s.js  代码:========

 

  1 (function($){
  2     'use strict';
  3     //浏览器支持transition样式对应的事件
  4     var mt = window.mt,
  5         transitionend = mt.name,
  6         isSupport     = mt.isSupport;
  7 
  8     //初始化对象$ele
  9     //等价于: var init = function($ele,callback){...}
 10     function init($ele,callback){
 11         if ($ele.is(':hidden')) {
 12             $ele.data('status','hidden');
 13             //判断callback的类型一定要是函数才行,否则不执行。
 14             if (typeof callback === 'function') callback();
 15         }else{
 16             $ele.data('status','shown');
 17         }
 18     }
 19 
 20     //显示
 21     function show($ele,callback){
 22         if ($ele.data('status') === 'show' || $ele.data('status') === 'shown') return;
 23         $ele.data('status','show').trigger('show');
 24         callback();
 25     }
 26     //隐藏
 27     function hide($ele,callback){
 28         if ($ele.data('status') === 'hide' || $ele.data('status') === 'hidden') return;
 29         $ele.data('status','hide').trigger('hide');
 30         callback();
 31     }
 32 
 33     //静静的显示,无动画
 34     var silent = {
 35         init:init,
 36         show:function($ele){
 37             show($ele,function(){
 38                 $ele.show();
 39                 $ele.data('status','shown').trigger('shown');
 40             });
 41         },
 42         hide:function($ele){
 43             hide($ele,function(){
 44                 $ele.hide();
 45                 $ele.data('status','hidden').trigger('hidden');
 46             });
 47         }
 48     }
 49 
 50     var css3 = {
 51         fade:{
 52             //init方法被调用时要传参数,所以一定一定记住。
 53             //不论在哪里都一样
 54             init:function($ele){
 55                 css3._init($ele,'fade');
 56             },
 57             //show方法被调用时要传参数,所以一定一定记住。
 58             //不论在哪里都一样
 59             show:function($ele){
 60                 css3._show($ele,'fade');
 61             },
 62             //hide方法被调用时要传参数,所以一定一定记住。
 63             //不论在哪里都一样
 64             hide:function($ele){
 65                 css3._hide($ele,'fade');
 66             }
 67         },
 68         slideUpDown:{
 69             //init方法被调用时要传参数,所以一定一定记住。
 70             //不论在哪里都一样
 71             init:function($ele){
 72                 css3._init($ele,'slideUpDown');
 73             },
 74             //show方法被调用时要传参数,所以一定一定记住。
 75             //不论在哪里都一样
 76             show:function($ele){
 77                 css3._show($ele,'slideUpDown');
 78             },
 79             //hide方法被调用时要传参数,所以一定一定记住。
 80             //不论在哪里都一样
 81             hide:function($ele){
 82                 css3._hide($ele,'slideUpDown');
 83             }
 84         },
 85         slideLeftRight:{
 86             //init方法被调用时要传参数,所以一定一定记住。
 87             //不论在哪里都一样
 88             init:function($ele){
 89                 css3._init($ele,'slideLeftRight');
 90             },
 91             //show方法被调用时要传参数,所以一定一定记住。
 92             //不论在哪里都一样
 93             show:function($ele){
 94                 css3._show($ele,'slideLeftRight');
 95             },
 96             //hide方法被调用时要传参数,所以一定一定记住。
 97             //不论在哪里都一样
 98             hide:function($ele){
 99                 css3._hide($ele,'slideLeftRight');
100             }
101         },
102         fadeSlideUpDown:{
103             //init方法被调用时要传参数,所以一定一定记住。
104             //不论在哪里都一样
105             init:function($ele){
106                 css3._init($ele,'fadeSlideUpDown');
107             },
108             //show方法被调用时要传参数,所以一定一定记住。
109             //不论在哪里都一样
110             show:function($ele){
111                 css3._show($ele,'fadeSlideUpDown');
112             },
113             //hide方法被调用时要传参数,所以一定一定记住。
114             //不论在哪里都一样
115             hide:function($ele){
116                 css3._hide($ele,'fadeSlideUpDown');
117             }
118         },
119         fadeSlideLeftRight:{
120             //init方法被调用时要传参数,所以一定一定记住。
121             //不论在哪里都一样
122             init:function($ele){
123                 css3._init($ele,'fadeSlideLeftRight');
124             },
125             //show方法被调用时要传参数,所以一定一定记住。
126             //不论在哪里都一样
127             show:function($ele){
128                 css3._show($ele,'fadeSlideLeftRight');
129             },
130             //hide方法被调用时要传参数,所以一定一定记住。
131             //不论在哪里都一样
132             hide:function($ele){
133                 css3._hide($ele,'fadeSlideLeftRight');
134             }
135         }
136     }
137     //css3 内部的 初始化对象$ele  公共部分
138     css3._init = function($ele,className){
139         //把可能需要修改的内容尽量写在最外面一层,不需要修改都尽量写在底层
140         //给对象添加过渡属性
141         $ele.addClass('transition');
142         init($ele,function(){
143             $ele.addClass(className);
144         });
145     }
146     //css3 内部的 显示的公共部分
147     css3._show = function($ele,className){
148         show($ele,function(){
149             $ele.off(transitionend).one(transitionend,function(){
150                 $ele.data('status','shown').trigger('shown');
151             });
152             $ele.show();
153             setTimeout(function(){
154                 $ele.removeClass(className);
155             },20);
156         });
157     }
158     //css3 内部的 隐藏的公共部分
159     css3._hide = function($ele,className){
160         hide($ele,function(){
161             $ele.off(transitionend).one(transitionend,function(){
162                 $ele.hide();
163                 $ele.data('status','hidden').trigger('hidden');
164             });
165             $ele.addClass(className);
166         });
167     }
168 
169     var js = {
170             fade:{//fadeIn() fadeOut() 淡入淡出
171                 init:function($ele){
172                     js._init($ele);
173                 },
174                 show:function($ele){
175                     js._show($ele,'fadeIn');
176                 },
177                 hide:function($ele){
178                     js._hide($ele,'fadeOut');
179                 }
180             },
181             slideUpDown:{// slideDown() slideUp()  上下滚动
182                 init:function($ele){
183                     js._init($ele);
184                 },
185                 show:function($ele){
186                     js._show($ele,'slideDown');
187                 },
188                 hide:function($ele){
189                     js._hide($ele,'slideUp');
190                 }
191             },
192             slideLeftRight:{
193                 init:function($ele){
194                     js._customInit($ele,{
195                         'width':'0',
196                         'padding-left':'0',
197                         'padding-right':'0'
198                     });
199                 },
200                 show:function($ele){
201                     js._customShow($ele);
202                 },
203                 hide:function($ele){
204                     js._customHide($ele,{
205                             'width':'0',
206                             'padding-left':'0',
207                             'padding-right':'0'
208                     });
209                 }
210             },
211             fadeSlideUpDown:{
212                 init:function($ele){
213                     js._customInit($ele,{
214                         'opacity':'0',
215                         'height':'0',
216                         'padding-top':'0',
217                         'padding-bottom':'0'
218                     });
219                 },
220                 show:function($ele){
221                     js._customShow($ele);
222                 },
223                 hide:function($ele){
224                     js._customHide($ele,{
225                         'opacity':'0',
226                         'height':'0',
227                         'padding-top':'0',
228                         'padding-bottom':'0'
229                     });
230                 }
231             },
232             fadeSlideLeftRight:{
233                 init:function($ele){
234                     js._customInit($ele,{
235                         'opacity':'0',
236                         'width':'0',
237                         'padding-left':'0',
238                         'padding-right':'0'
239                     });
240                 },
241                 show:function($ele){
242                     js._customShow($ele);
243                 },
244                 hide:function($ele){
245                     js._customHide($ele,{
246                         'opacity':'0',
247                         'width':'0',
248                         'padding-left':'0',
249                         'padding-right':'0'
250                     });
251                 }
252             }
253     }
254 
255     js._init = function($ele){
256         //1,这里使用的是JS进行显示隐藏,所以就不用css代码来实现
257         //2,移除 .transition css写法的类,是为了防止进行两次动画。而出现异常
258         $ele.removeClass('transition');
259         init($ele);
260     }
261     js._customInit = function($ele,options){
262         //只用js进行操作,防止添加CSS .transition类名的出现异常
263         $ele.removeClass('transition');
264         //就是页面加载的时候就获得该对象的数据
265         var styles = {};
266         for (var p in options) {
267             styles[p] = $ele.css(p);
268         }
269         //把值放到$ele标签中进行传递
270         $ele.data('styles',styles);
271 
272         init($ele,function(){
273             $ele.css(options);
274         });
275     };
276     js._show = function($ele,mode){
277         show($ele,function(){
278             $ele.stop()[mode](function(){
279                 $ele.data('status','shown').trigger('shown');
280             });
281         });
282     };
283     js._customShow = function($ele){
284         show($ele,function(){
285             var styles = $ele.data('styles');//获取对象的属性
286             $ele.show();
287             $ele.stop().animate(styles, function() {
288                 $ele.data('status','shown').trigger('shown');
289             });
290         });
291     };
292     js._hide = function($ele,mode){
293         hide($ele,function(){
294             $ele.stop()[mode](function(){
295                 $ele.data('status','hidden').trigger('hidden');
296             });
297         });
298     };
299     js._customHide = function($ele,options){
300         hide($ele,function(){
301             $ele.stop().animate(options, function() {
302                 $ele.hide();
303                 $ele.data('status','hidden').trigger('hidden');
304             });
305         })
306     }
307 
308 /*
309     //需要传的参数,及传时的默认参数
310     var defaults = {
311         css3:false,
312         js:false,
313         animation:'fade'
314     };
315 
316     function showHide($ele,options){
317         //将两个或更多对象的内容合并到第一个对象。第一个对象中没有的内容才能添加进去。
318         options = $.extend({},defaults,options);
319         var mode = null;
320         if (options.css3 && isSupport) {//css animation
321             mode = css3[options.animation] || css3[defaults.animation];
322         }else if (options.js){//js animation
323             mode = js[options.animation] || js[defaults.animation];
324         }else {//no animation
325             mode = silent;
326         };
327 
328         mode.init($ele);
329         return {
330             show:mode.show,
331             hide:mode.hide
332             // show:$.proxy(mode.show,this,$ele),
333             // hide:$.proxy(mode.hide,this,$ele)
334         };
335         // if (options.css3 && transition.isSupport) {//css animation
336         //     css3[options.animation].init($ele);
337         //     return {
338         //         show:css3[options.animation].show,
339         //         hide:css3[options.animation].hide
340         //     };
341         // }else if (options.js){//js animation
342         //     js[options.animation].init($ele);
343         //     return {
344         //         show:js[options.animation].show,
345         //         hide:js[options.animation].hide
346         //     }
347         // }else {//no animation
348         //     silent.init($ele);
349         //     return {
350         //         show:silent.show,
351         //         hide:silent.hide
352         //     };
353         // }
354     }
355 
356     //短路操作,如果window.mt = undefined / [空字符串],隐式转换为false。
357     //则创建一个空对象,window.mt = {};
358     //window.mt = 对象/字符串,则就使用该对象
359     window.mt = window.mt || {};
360 
361     window.mt.showHide = showHide;
362     */
363 
364 
365     //有三个对象要调用 silent,css3,js
366     //cilent  [ show,hide ]
367     //css3 [ show,hidee ]
368     //js  [ show,hide]
369 var defaults = {
370     css3:true,
371     js:false,
372     animation:'fade'
373 }
374 
375 /**
376  * 返回一个对象,两个方法show hide
377  * @param  {obj} $ele    jquery对象
378  * @param  {obj} options 对象三个参数,指定使用哪种方式显示
379  * @return {返回一个对象}         包括show(),hide()
380  */
381 function showHide($ele,options){
382     //如果参数传的不正确,则使用默认参数
383     //将两个或更多对象的内容合并到第一个对象。第一个对象中没有的内容才能添加进去。
384     // options = $.extend({},defaults,options);
385     var mode;
386 
387     //判断是哪种方式为true,就选择哪种方式进行显示
388     if (options.css3 && isSupport) {
389         mode = css3[options.animation] || css3.fade;
390     }else if (options.js){
391         mode = js[options.animation] || js.fade;
392     }else{
393         mode = silent;
394     }
395     mode.init($ele);
396 
397     return {
398         // show:mode.show, //被调用时,show函数是要传显示对象的。
399         // hide:mode.hide //被调用时,hide函数是要传隐藏对象的。
400         show:$.proxy(mode.show,this,$ele),
401         hide:$.proxy(mode.hide,this,$ele)
402     }
403 
404 }
405 //创建对外可以调用的接口
406 window.mt = window.mt || {};
407 window.mt.showHide = showHide;
408 
409 
410 //封装成插件,语法:$.fn.extend({name:function(){...}})
411     $.fn.extend({
412         //插件名称:function(){...}
413         showHide:function(option){
414             //根据option参数不同,返回值不同
415             //1,参数为object  返回this,就是返回当前调用的对象
416             //     each(...)  表示哪种类型的 this 而已
417             //     使用$box.showHide({css:true,js:flase,animation:slideUpDown})
418             //     返回的是 另一个 样式不同的 this,对象是不变的,还是返回$box对象,这个对象可能隐藏,可能显示。
419             //     返回值:k.fn.init [div.box.transition.slideUpDown, prevObject: k.fn.init(1)]
420             return this.each(function(){
421                 var $this = $(this),//调用当前该插件的对象
422 
423                     //$.extend 合并多个对象的属性,返回到第一个对象中。
424                     //typeof option === 'object' && option 短路操作,非常重要,
425                     //解析:
426                     //1,typeof option === 'object'   为true   则返回 option对象 ,option覆盖defaults,返回一个新对象
427                     //2,typeof option === 'object'   为false  则返回 false 所以这里options = defaults。
428                     options = $.extend({},defaults,typeof option === 'object' && option),
429                     //从当前标签中获取showHide的值,该值存放的是具体的操作方式
430                     mode = $this.data('showHide');
431                 //如果该操作方式的的值为空,那么就执行一次showHide获取操作方式,并存放在当前调用的标签中。
432                 //这里的函数只执行一次,效率高。性能好。
433                 if (!mode) {
434                     $this.data('showHide',mode=showHide($this,options));
435                 }
436 
437                 //mode 是操作方式   mode[option]如果是show hide 就是显示隐藏,只要判断是否是函数即可
438                 //当option是字符串,且该字符跟mode组合,返回是函数时,就直接执行该函数。
439                 if (typeof mode[option] === 'function') {
440                     mode[option]();
441                 }
442             })
443         }
444     })
445 })(jQuery)

创建四个文件,引入两个 jquery.js 文件即可正常显示隐藏操作

posted @ 2019-08-19 09:54  最好的安排  阅读(761)  评论(0编辑  收藏  举报

Knowledge is infinite