[关闭]
@GivenCui 2016-08-11T21:26:45.000000Z 字数 5659 阅读 624

用构造函数重写Tab选项卡

深入理解


目录


要点总结

要点:

变形 :
1.先变型:
2.尽量不要出现函数嵌套函数
3.可以有全局变量
4.把onload中不是赋值的语句放到单独函数中

改成面向对象 :
1.全局变量就是属性
2.函数就是方法
3.Onload中创建对象
4.事件或定时器会改变this指向,尽量让面向对象中的this指向对象


注意事项
1. init() 中添加事件绑定后续所有功能函数 (方便改写事件类型)
2. 功能函数中 先恢复初值, 再实现功能

tab点击重构详解

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <style>
  7. #div1 div,#div2 div{ width:200px; height:200px; border:1px #000 solid; display:none;}
  8. .active{ background:red;}
  9. </style>
  10. <script>
  11. ///////////////////////////////////////////////////////////////// //
  12. /// 第一步骤 : 面向过程实现功能 //
  13. ////////////////////////////////////////////////////////////////////
  14. // window.onload = function () {
  15. // var box1 = document.querySelector("#div1");
  16. // var aBtn1 = box1.querySelectorAll("input");
  17. // var tabs1 = box1.querySelectorAll("div");
  18. // 方法一: for循环
  19. // for (var i = 0; i < aBtn1.length; i++) {
  20. // // 添加自定义index
  21. // aBtn1[i].index = i;
  22. // aBtn1[i].onclick = function () {
  23. // // 恢复所有原样式
  24. // for (var i = 0; i < aBtn1.length; i++) {
  25. // tabs1[i].style.display = "none";
  26. // aBtn1[i].className = "";
  27. // }
  28. // // 点击加样式
  29. // this.className = "active";
  30. // tabs1[this.index].style.display = "block";
  31. // }
  32. // }
  33. /*
  34. // 方法二: [].forEack.call()
  35. // 练习[].forEach.call()的这种
  36. [].forEach.call(aBtn1, function (ele,idx) {
  37. ele.index = idx;
  38. ele.onclick = function () {
  39. for (var i = 0; i < aBtn1.length; i++) {
  40. tabs1[i].style.display = "none";
  41. aBtn1[i].className = "";
  42. }
  43. ele.className = "active";
  44. tabs1[this.index].style.display = "block";
  45. }
  46. })
  47. */
  48. // 方法三: for of
  49. // } // onload 结束
  50. ///////////////////////////////////////////////////////////////// //
  51. /// 第二步骤 : 变形 //
  52. ////////////////////////////////////////////////////////////////////
  53. //先变型:
  54. //尽量不要出现函数嵌套函数
  55. //可以有全局变量
  56. //把onload中不是赋值的语句放到单独函数中
  57. // 第一组
  58. // ////////////////////全局变量///////////////////////////
  59. // var box1 = null;
  60. // var aBtn1 = null;
  61. // var tabs1 = null;
  62. // ///////////////////window.onload部分/////////////////
  63. // window.onload = function () {
  64. // // 第一组
  65. // box1 = document.querySelector("#div1")
  66. // aBtn1 = box1.querySelectorAll("input");
  67. // tabs1 = box1.querySelectorAll("div");
  68. // // 调用init函数
  69. // init()
  70. // }; // onload 结束
  71. // ///////////////事件绑定函数////////////////////////////
  72. // // init函数
  73. // // 借鉴模板设计模式
  74. // function init () {
  75. // for(var i = 0; i < aBtn1.length; i++) {
  76. // aBtn1[i].index = i;
  77. // // 点击事件调用change函数
  78. // aBtn1[i].onclick = change;
  79. // }
  80. // }
  81. // // change函数
  82. // function change () {
  83. // // 恢复默认样式
  84. // for ( var i=0; i < aBtn1.length; i++) {
  85. // aBtn1[i].className = "";
  86. // tabs1[i].style.display = "none";
  87. // }
  88. // // 事件触发样式
  89. // // 这两个this是onclick的aBtn1[i]
  90. // tabs1[this.index].style.display = "block";
  91. // this.className = "active";
  92. // }
  93. ///////////////////////////////////////////////////////////////// //
  94. /// 第三步骤 : 面向对象封装 //
  95. ////////////////////////////////////////////////////////////////////
  96. //改成面向对象:
  97. //全局变量就是属性
  98. //函数就是方法
  99. //Onload中创建对象
  100. //改this指向问题 : 事件或者是定时器,尽量让面向对象中的this指向对象
  101. window.onload = function () {
  102. var box1 = document.querySelector("#div1");
  103. var aBtn1 = box1.querySelectorAll("input");
  104. var aDiv1 = box1.querySelectorAll("div");
  105. var t1 = new Tab(aBtn1, aDiv1);
  106. t1.init();
  107. }
  108. // 构造函数
  109. function Tab (a , b) {
  110. this.a = a;
  111. this.b = b;
  112. }
  113. // prototype添加方法
  114. // 模板方法
  115. // 事件在这里添加
  116. // 优点是很容易换事件的类型
  117. Tab.prototype.init = function () {
  118. var that = this;
  119. for(var i = 0; i < this.a.length; i ++) {
  120. this.a[i].index = i;
  121. // 这里的this因onclick而改变
  122. this.a[i].onclick = function () {
  123. // 函数是被onclick调用
  124. // 这里的this指代按钮
  125. that.change(this);
  126. };
  127. }
  128. };
  129. // 点击切换功能
  130. Tab.prototype.change = function (target) {
  131. var objA = this.a;
  132. var objB = this.b;
  133. // 恢复原样式
  134. for (var i = 0; i < objA.length; i++) {
  135. objA[i].className = "";
  136. objB[i].style.display = "none";
  137. }
  138. // 事件改变的样式
  139. target.className = "active";
  140. objB[target.index].style.display = "block";
  141. };
  142. </script>
  143. </head>
  144. <body>
  145. <div id="div1">
  146. <input class="active" type="button" value="1">
  147. <input type="button" value="2">
  148. <input type="button" value="3">
  149. <div style="display:block">11111</div>
  150. <div>22222</div>
  151. <div>33333</div>
  152. </div>
  153. <div id="div2">
  154. <input class="active" type="button" value="1">
  155. <input type="button" value="2">
  156. <input type="button" value="3">
  157. <div style="display:block">11111</div>
  158. <div>22222</div>
  159. <div>33333</div>
  160. </div>
  161. </body>
  162. </html>

tab点击和轮播

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <title>无标题文档</title>
  6. <style>
  7. #div1,#div2{
  8. width: 200px;
  9. }
  10. #div1 div,#div2 div{ width:200px; height:200px; border:1px #000 solid; display:none;background: green;}
  11. .active{ background:red;}
  12. </style>
  13. <script>
  14. /*var arr = [4,7,1,3];
  15. arr.sort(); // 1 3 4 7
  16. var arr2 = [4,7,1,3];
  17. arr2.push(5);
  18. arr2.sort(); // 1 3 4 5 7
  19. */
  20. window.onload = function(){
  21. var t1 = new Tab('div1');
  22. t1.init();
  23. // t1.autoPlay();
  24. var t2 = new Tab('div2');
  25. t2.init();
  26. t2.autoPlay();
  27. };
  28. function Tab(id){
  29. this.oParent = document.getElementById(id);
  30. this.aInput = this.oParent.getElementsByTagName('input');
  31. this.aDiv = this.oParent.getElementsByTagName('div');
  32. this.iNow = 0;
  33. }
  34. Tab.prototype.init = function(){
  35. var This = this;
  36. for(var i=0;i<this.aInput.length;i++){
  37. this.aInput[i].index = i;
  38. this.aInput[i].onclick = function(){
  39. This.change(this);
  40. };
  41. }
  42. };
  43. Tab.prototype.change = function(obj){
  44. for(var i=0;i<this.aInput.length;i++){
  45. this.aInput[i].className = '';
  46. this.aDiv[i].style.display = 'none';
  47. }
  48. obj.className = 'active';
  49. this.aDiv[obj.index].style.display = 'block';
  50. this.iNow = obj.index;
  51. };
  52. Tab.prototype.autoPlay = function(){
  53. var timer = null;
  54. clearInterval(timer);
  55. var This = this;
  56. timer = setInterval(function(){
  57. if(This.iNow == This.aInput.length-1){
  58. This.iNow = 0;
  59. } else {
  60. This.iNow++;
  61. }
  62. for(var i=0;i<This.aInput.length;i++){
  63. This.aInput[i].className = '';
  64. This.aDiv[i].style.display = 'none';
  65. }
  66. This.aInput[This.iNow].className = 'active';
  67. This.aDiv[This.iNow].style.display = 'block';
  68. },1000);
  69. This.oParent.onmouseover = function () {
  70. clearInterval(timer);
  71. };
  72. This.oParent.onmouseout = function () {
  73. This.autoPlay();
  74. };
  75. };
  76. </script>
  77. </head>
  78. <body>
  79. <div id="div1">
  80. <input class="active" type="button" value="1">
  81. <input type="button" value="2">
  82. <input type="button" value="3">
  83. <div style="display:block">11111</div>
  84. <div>22222</div>
  85. <div>33333</div>
  86. </div>
  87. <div id="div2">
  88. <input class="active" type="button" value="1">
  89. <input type="button" value="2">
  90. <input type="button" value="3">
  91. <div style="display:block">11111</div>
  92. <div>22222</div>
  93. <div>33333</div>
  94. </div>
  95. </body>
  96. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注