4-3 代码封装
本节编程练习不计算学习进度,请电脑登录imooc.com操作

代码封装

初学着写JS可以说都是毫无章法可言的,基本上是想到什么就写什么,就是一个接一个的函数function,遇到重复的还得copy,如果一不小心函数重名了,还真不知道从何开始查找错误,因为大家总是用面向过程的编程思想来写JS代码。当然也不是错误,只是从长远的发展角度来说,我们更希望代码是易维护、易扩展的也是程序员经常挂在嘴边的口头禅"高内聚 低耦合"。

基础性的东西这里不过多讨论。以圣诞主题为例,拥有3个场景页面,在设计上,我会将每一个场景当作一个独立的"场景对象",场景内部都封装了各自的子对象,对象与对象之间通过接口调用。简单的说就是将行为封装分布在各个对象中,并让这些对象自己各自负责自己的行为,这也是面向对象设计的一个优点。

就拿页面切换的效果来说,场景A需要切换到场景B,那么元素A不需要关心页面是怎么切换的,它只能要调用到一个接口方法能让页面切换就行了

基于这样的理论,我们就开始简单的改造整个代码结构这块

设计3个独立的JS文件分别是page-a.js、page-b.js、page-c.js,分别对应了3个场景类,把每一个场景的内容封装到每一个场景类中

然后在三个场景类之间通过接口去调用,比如切换页面,所以需要创建一个"中介"对象(christmas.js)充当,接口分配任务。

JavaScript的的类的概念也不是那么"正宗的",同时也没有规范上的抽象类与接口的支持,所以很大程度上实现封装都是靠闭包去模拟,具体可以参考右边代码区域

任务

  1. <!DOCTYPE html>
  2. <html>
  3.  
  4. <head>
  5. <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
  6. <title>圣诞主题</title>
  7. <link rel='stylesheet' href='common.css' />
  8. <script src="http://libs.baidu.com/jquery/1.9.1/jquery.js"></script>
  9. <script src="pageC.js"></script>
  10. <script src="pageB.js"></script>
  11. <script src="pageA.js"></script>
  12. <script src="christmas.js"></script>
  13. </head>
  14.  
  15. <body>
  16. <section class="container">
  17. <!-- 第一幅画面 -->
  18. <section class="page-a bg-adaptive">
  19. </section>
  20. <!-- 第二幅画面 -->
  21. <section class="page-b bg-adaptive">
  22. </section>
  23. <!-- 第三幅画面 -->
  24. <section class="page-c bg-adaptive">
  25. </section>
  26. </section>
  27. 选择页面:
  28. <select id="choose">
  29. <option value="page-a" selected="">1</option>
  30. <option value="page-b">2</option>
  31. <option value="page-c">3</option>
  32. </select>
  33. <script type="text/javascript">
  34. /**
  35. * 自适应页面大小
  36. * @param {[type]} doc [description]
  37. * @param {[type]} win [description]
  38. * @return {[type]} [description]
  39. */
  40. var docEl = document.documentElement,
  41. resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
  42. recalc = function() {
  43. //自适应设置容器高度
  44. var container = document.querySelector(".container")
  45. //原始比例
  46. var proportion = 900 / 1440;
  47. container.style.height = container.clientWidth * proportion + "px";
  48. };
  49. window.addEventListener(resizeEvt, recalc, false);
  50. document.addEventListener('DOMContentLoaded', recalc, false);
  51. </script>
  52. </body>
  53.  
  54. </html>
  55.  
  1. /**
  2.  * 慕课网特制
  3.  * 圣诞主题效果
  4.  * @type {Object}
  5.  */
  6.  
  7. /**
  8.  * 切换页面
  9.  * 模拟镜头效果
  10.  * @return {[type]} [description]
  11.  */
  12. function changePage(element,effect,callback){
  13. element
  14. .addClass(effect)
  15. .one("animationend webkitAnimationEnd", function() {
  16. callback && callback();
  17. })
  18. }
  19.  
  20.  
  21. /**
  22.  * 中间调用
  23.  */
  24. var Christmas = function() {
  25. //页面容器元素
  26. var $pageA = $(".page-a");
  27. var $pageB = $(".page-b");
  28. var $pageC = $(".page-c");
  29.  
  30. //切换切换
  31. $("#choose").on("change", function(e) {
  32. //页面名称
  33. var pageName = e.target.value;
  34. switch (pageName) {
  35. case "page-b":
  36. //切换到页面B,然后捕获到切换后的通知
  37. changePage($pageA, "effect-out", function() {
  38. new pageB()
  39. })
  40. break;
  41. case "page-c":
  42. //切换到页面C,然后捕获到切换后的通知
  43. changePage($pageC, "effect-in", function() {
  44. new pageC()
  45. })
  46. break;
  47. }
  48. })
  49.  
  50. };
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57. $(function() {
  58. //圣诞主题效果,开始
  59. Christmas()
  60. })
  1.  
  2. function pageA (argument) {
  3. alert("页面C")
  4. }
  1.  
  2. function pageB (argument) {
  3. alert("页面B")
  4. }
  1.  
  2. function pageC (argument) {
  3. alert("页面C")
  4. }
  1. *{
  2. margin: 0;
  3. padding: 0;
  4. }
  5.  
  6. /*body{
  7.   width: 100%;
  8.   height: 100%;
  9. }*/
  10.  
  11. .container {
  12. width: 100%;
  13. height: 100%;
  14. position: relative;
  15. overflow: hidden;
  16. }
  17.  
  18. .bg-adaptive {
  19. background-size: 100% 100%;
  20. }
  21.  
  22. .container .page-a {
  23. width : 100%;
  24. height : 100%;
  25. background-image: url("http://img1.sycdn.imooc.com//565d07770001790814410901.png");
  26. position: absolute;
  27. z-index: 5;
  28. }
  29.  
  30. .container .page-b {
  31. width : 100%;
  32. height : 100%;
  33. background-image: url("http://img1.sycdn.imooc.com//565d09fa000145a614410901.png");
  34. position: absolute;
  35. z-index: 4;
  36. }
  37.  
  38. .page-c {
  39. width : 100%;
  40. height : 100%;
  41. background-image: url("http://img1.sycdn.imooc.com//565d0b280001788014410901.png");
  42. position: absolute;
  43. z-index: 3;
  44. }
  45.  
  46.  
  47.  
  48.  
  49. /**
  50.  * 页面切换
  51.  * 镜头方法
  52.  */
  53. .effect-out{
  54. -webkit-animation: effectOut 8s ease-in-out forwards;
  55. -webkit-transform-origin:71% 72%;
  56. -moz-animation: effectOut 8s ease-in-out forwards;
  57. -moz-transform-origin:71% 72%;
  58.  
  59.  
  60. }
  61. @-webkit-keyframes effectOut{
  62. 0% { opacity:1; }
  63. 100% { -webkit-transform: scale(20); opacity:0; }
  64. }
  65. @-moz-keyframes effectOut{
  66. 0% { opacity:1; }
  67. 100% { -moz-transform: scale(20); opacity:0; }
  68. }
  69.  
  70. .effect-in{
  71. z-index: 15;
  72. display: block;
  73. opacity:0;
  74. -webkit-transform: scale(8);
  75. -webkit-animation: effectIn 5s ease-in-out forwards;
  76. -webkit-transform-origin:58.5% 73.5%;
  77. -moz-transform: scale(8);
  78. -moz-animation: effectIn 5s ease-in-out forwards;
  79. -moz-transform-origin:58.5% 73.5%;
  80.  
  81.  
  82. }
  83. @-webkit-keyframes effectIn{
  84. 100% { -webkit-transform: scale(1); opacity:1; }
  85. }
  86. @-moz-keyframes effectIn{
  87. 100% { -moz-transform: scale(1); opacity:1; }
  88. }
下一节