[关闭]
@fantaghiro 2014-11-17T06:15:16.000000Z 字数 42225 阅读 1642

妙味课堂 - JS面向对象

学习笔记 妙味课堂 js


什么是面向对象编程

面向对象编程(OOP)的特点

对象的组成

创建第一个面向对象程序

  1. //var obj = {};
  2. var obj = new Object(); //创建了一个空的对象
  3. obj.name = '小明'; //属性
  4. obj.showName = function(){ //方法
  5. alert(this.name);
  6. }
  7. obj.showName();
  1. //var obj = {};
  2. var obj = new Object(); //创建了一个空的对象
  3. obj.name = '小明'; //属性
  4. obj.showName = function(){ //方法
  5. alert(this.name);
  6. }
  7. obj.showName();
  8. var obj2 = new Object();
  9. obj2.name = '小强';
  10. obj.showName = function(){
  11. alert(this.name);
  12. }
  13. obj2.showName();

工厂方式

  1. //工厂方式:封装函数
  2. function createPerson(name){
  3. //1. 原料
  4. var obj = new Object();
  5. //2. 加工
  6. obj.name = name;
  7. obj.showName = function(){
  8. alert(this.name);
  9. };
  10. //3. 出厂
  11. return obj;
  12. }
  13. var p1 = createPerson('小明');
  14. p1.showName();
  15. var p2 = createPerson('小强');
  16. p2.showName();
  1. /* 当new去调用一个函数:这个时候函数中的this就是创建出来的对象,而且函数的返回值直接就是this啦。(这叫做隐式返回) */
  2. // new后面调用的函数:构造函数
  3. function CreatePerson(name){
  4. this.name = name;
  5. this.showName = function(){
  6. alert(this.name);
  7. };
  8. // return obj; 隐式返回,所以这一行不用写了
  9. }
  10. var p1 = new CreatePerson('小明');
  11. p1.showName();
  12. var p2 = new CreatePerson('小强');
  13. p2.showName();
  1. /* 当new去调用一个函数:这个时候函数中的this就是创建出来的对象,而且函数的返回值直接就是this啦。(这叫做隐式返回) */
  2. // new后面调用的函数:构造函数
  3. function CreatePerson(name){
  4. this.name = name;
  5. this.showName = function(){
  6. alert(this.name);
  7. };
  8. // return obj; 隐式返回,所以这一行不用写了
  9. }
  10. var p1 = new CreatePerson('小明');
  11. p1.showName();
  12. var p2 = new CreatePerson('小强');
  13. p2.showName();
  14. //alert(p1.showName == p2.showName); //false
  1. /*
  2. var a = [1, 2, 3];
  3. var b = [1, 2, 3];
  4. alert(a == b); //false;
  5. */
  6. /*
  7. var a = 5;
  8. var b = a;
  9. b += a;
  10. alert(b); //8
  11. alert(a); //5 基本类型:赋值的时候只是值的复制
  12. */
  13. /*
  14. var a = [1, 2, 3];
  15. var b = a;
  16. b.push(4);
  17. alert(b); //[1, 2, 3, 4]
  18. alert(a); //[1, 2, 3, 4] 对象类型:赋值不仅是值的复制,而且也是引用的传递
  19. */
  20. /*
  21. var a = [1, 2, 3];
  22. var b = a;
  23. b = [1, 2, 3, 4];
  24. alert(b); //[1, 2, 3, 4]
  25. alert(a); //[1, 2, 3] 只要赋值就会在内存中重新生成,所以a,b互补影响
  26. */
  27. /*
  28. var a = 5;
  29. var b = 5;
  30. alert(a == b); //true 基本类型的比较:只要值相同就可以
  31. */
  32. /*
  33. var a = [1, 2, 3];
  34. var b = [1, 2, 3];
  35. alert(a == b); //false 对象类型:值和引用都相同才行
  36. */
  37. /*
  38. var a = [1, 2, 3];
  39. var b = a;
  40. alert(a == b); //true
  41. */

原型 —— prototype

  1. var arr = [];
  2. arr.number = 10;
  3. Array.prototype.number = 20;
  4. alert(arr.number); //10 普通方法的优先级高于原型
  1. //原型:prototype:要写在构造函数下面
  2. var arr = [1, 2, 3, 4, 5];
  3. var arr2 = [2, 2, 2, 2, 2];
  4. Array.prototype.sum = function(){
  5. var result = 0;
  6. for(var i=0; i<this.length; i++){
  7. result += this[i];
  8. }
  9. return result;
  10. }
  11. /*
  12. arr.sum = function(){
  13. var result = 0;
  14. for(var i=0; i<this.length; i++){
  15. result += this[i];
  16. }
  17. return result;
  18. }
  19. alert(arr.sum()); //15
  20. */
  21. alert(arr.sum());
  22. alert(arr2.sum());
  1. function CreatePerson(name){
  2. this.name = name; //变化的,不能公用的属性不能写在原型上
  3. }
  4. CreatePerson.prototype.showName = function(){
  5. alert(this.name);
  6. }
  7. var p1 = new CreatePerson('小明');
  8. var p2 = new CreatePerson('小强');
  9. alert(p1.showName == p2.showName); //true

混合的编程模式

  1. //面向对象的写法
  2. function 构造函数(){
  3. this.属性
  4. }
  5. 构造函数.原型.方法 = function(){};
  6. //面向对象的使用
  7. var 对象1 = new 构造函数();
  8. 对象1.方法();

面向对象的选项卡

先写出普通方法

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象的选项卡</title>
  6. <style>
  7. #div1 div { width: 200px; height: 200px; border: 1px solid #000; display: none; }
  8. .active { background: red; }
  9. </style>
  10. <script>
  11. window.onload = function(){
  12. var oParent = document.getElementById('div1');
  13. var aInput = oParent.getElementsByTagName('input');
  14. var aDiv = oParent.getElementsByTagName('div');
  15. for(var i=0; i<aInput.length; i++){
  16. aInput[i].index = i;
  17. aInput[i].onclick = function(){
  18. for(var i=0; i<aInput.length; i++){
  19. aInput[i].className = '';
  20. aDiv[i].style.display = 'none';
  21. }
  22. this.className = 'active';
  23. aDiv[this.index].style.display = 'block';
  24. }
  25. }
  26. }
  27. </script>
  28. </head>
  29. <body>
  30. <div id="div1">
  31. <input type="button" value="1" class="active">
  32. <input type="button" value="2">
  33. <input type="button" value="3">
  34. <div style="display: block">11111</div>
  35. <div>22222</div>
  36. <div>33333</div>
  37. </div>
  38. </body>
  39. </html>

普通方法变型

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象的选项卡</title>
  6. <style>
  7. #div1 div { width: 200px; height: 200px; border: 1px solid #000; display: none; }
  8. .active { background: red; }
  9. </style>
  10. <script>
  11. var oParent = null;
  12. var aInput = null;
  13. var aDiv = null;
  14. window.onload = function(){
  15. oParent = document.getElementById('div1');
  16. aInput = oParent.getElementsByTagName('input');
  17. aDiv = oParent.getElementsByTagName('div');
  18. init();
  19. };
  20. function init(){ //初始化的函数方法
  21. for(var i=0; i<aInput.length; i++){
  22. aInput[i].index = i;
  23. aInput[i].onclick = change;
  24. }
  25. }
  26. function change(){
  27. for(var i=0; i<aInput.length; i++){
  28. aInput[i].className = '';
  29. aDiv[i].style.display = 'none';
  30. }
  31. this.className = 'active';
  32. aDiv[this.index].style.display = 'block';
  33. }
  34. /*
  35. - 普通方法变型
  36. - 尽量不要出现函数嵌套函数
  37. - 可以有全局变量
  38. - 把onload中不是赋值的语句放到单独的函数中
  39. */
  40. </script>
  41. </head>
  42. <body>
  43. <div id="div1">
  44. <input type="button" value="1" class="active">
  45. <input type="button" value="2">
  46. <input type="button" value="3">
  47. <div style="display: block">11111</div>
  48. <div>22222</div>
  49. <div>33333</div>
  50. </div>
  51. </body>
  52. </html>

关于this的指向

  1. oDiv.onclick = function(){
  2. this: oDiv
  3. };
  4. ---
  5. oDiv.onclick = show;
  6. function show(){
  7. this: oDiv
  8. }
  9. ---
  10. oDiv.onclick = function(){
  11. show();
  12. };
  13. function show(){
  14. this: window
  15. }

改写成面向对象

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象bianxie</title>
  6. <style>
  7. #div1 div { width: 200px; height: 200px; border: 1px solid #000; display: none; }
  8. .active { background: red; }
  9. </style>
  10. <script>
  11. var oParent = null;
  12. var aInput = null;
  13. var aDiv = null;
  14. window.onload = function(){
  15. var t1 = new Tab();
  16. t1.init();
  17. };
  18. function Tab(){
  19. this.oParent = document.getElementById('div1');
  20. this.aInput = this.oParent.getElementsByTagName('input');
  21. this.aDiv = this.oParent.getElementsByTagName('div');
  22. }
  23. Tab.prototype.init = function(){
  24. var This = this;
  25. for(var i=0; i<this.aInput.length; i++){
  26. this.aInput[i].index = i;
  27. this.aInput[i].onclick = function(){
  28. This.change(this);
  29. };
  30. }
  31. }
  32. Tab.prototype.change = function(obj){
  33. for(var i=0; i<this.aInput.length; i++){
  34. this.aInput[i].className = '';
  35. this.aDiv[i].style.display = 'none';
  36. }
  37. obj.className = 'active';
  38. this.aDiv[obj.index].style.display = 'block';
  39. }
  40. /*
  41. - 改成面向对象
  42. - 全局变量就是属性
  43. - 函数就是方法
  44. - onload中创建对象
  45. - 改this指向问题:注意事件或者是定时器里面的this。要尽量保持面向对象中的this指向对象
  46. */
  47. </script>
  48. </head>
  49. <body>
  50. <div id="div1">
  51. <input type="button" value="1" class="active">
  52. <input type="button" value="2">
  53. <input type="button" value="3">
  54. <div style="display: block">11111</div>
  55. <div>22222</div>
  56. <div>33333</div>
  57. </div>
  58. </body>
  59. </html>

面向对象的复用

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象bianxie</title>
  6. <style>
  7. #div1 div, #div2 div { width: 200px; height: 200px; border: 1px solid #000; display: none; }
  8. .active { background: red; }
  9. </style>
  10. <script>
  11. var oParent = null;
  12. var aInput = null;
  13. var aDiv = null;
  14. window.onload = function(){
  15. var t1 = new Tab('div1');
  16. t1.init();
  17. var t2 = new Tab('div2');
  18. t2.init();
  19. t2.autoplay();
  20. };
  21. function Tab(id){
  22. this.oParent = document.getElementById(id);
  23. this.aInput = this.oParent.getElementsByTagName('input');
  24. this.aDiv = this.oParent.getElementsByTagName('div');
  25. this.iNow = 0;
  26. }
  27. Tab.prototype.init = function(){
  28. var This = this;
  29. for(var i=0; i<this.aInput.length; i++){
  30. this.aInput[i].index = i;
  31. this.aInput[i].onclick = function(){
  32. This.change(this);
  33. };
  34. }
  35. }
  36. Tab.prototype.change = function(obj){
  37. for(var i=0; i<this.aInput.length; i++){
  38. this.aInput[i].className = '';
  39. this.aDiv[i].style.display = 'none';
  40. }
  41. obj.className = 'active';
  42. this.aDiv[obj.index].style.display = 'block';
  43. }
  44. Tab.prototype.autoplay = function(){
  45. var This = this;
  46. setInterval(function(){
  47. if(This.iNow == This.aInput.length - 1){
  48. This.iNow = 0;
  49. } else {
  50. This.iNow ++;
  51. }
  52. for(var i=0; i<This.aInput.length; i++){
  53. This.aInput[i].className = '';
  54. This.aDiv[i].style.display = 'none';
  55. }
  56. This.aInput[This.iNow].className = 'active';
  57. This.aDiv[This.iNow].style.display = 'block';
  58. }, 2000)
  59. }
  60. </script>
  61. </head>
  62. <body>
  63. <div id="div1">
  64. <input type="button" value="1" class="active">
  65. <input type="button" value="2">
  66. <input type="button" value="3">
  67. <div style="display: block">11111</div>
  68. <div>22222</div>
  69. <div>33333</div>
  70. </div>
  71. <div id="div2">
  72. <input type="button" value="1" class="active">
  73. <input type="button" value="2">
  74. <input type="button" value="3">
  75. <div style="display: block">11111</div>
  76. <div>22222</div>
  77. <div>33333</div>
  78. </div>
  79. </body>
  80. </html>

面向对象的拖拽

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象编写拖拽</title>
  6. <style>
  7. #div1 { width: 100px; height: 100px; background: red; position: absolute; }
  8. </style>
  9. <script>
  10. /* 普通拖拽
  11. window.onload = function(){
  12. var oDiv = document.getElementById('div1');
  13. var disX = 0;
  14. var disY = 0;
  15. oDiv.onmousedown = function(ev){
  16. var ev = ev || window.event;
  17. disX = ev.clientX - oDiv.offsetLeft;
  18. disY = ev.clientY - oDiv.offsetTop;
  19. document.onmousemove = function(ev){
  20. var ev = ev || window.event;
  21. oDiv.style.left = ev.clientX - disX + 'px';
  22. oDiv.style.top = ev.clientY - disY + 'px';
  23. }
  24. document.onmouseup = function(){
  25. document.onmousemove = null;
  26. document.onmouseup = null;
  27. }
  28. return false;
  29. }
  30. }
  31. */
  32. /* 第一步:普通方法变型
  33. //先变型
  34. var oDiv = null;
  35. var disX = 0;
  36. var disY = 0;
  37. window.onload = function(){
  38. oDiv = document.getElementById('div1');
  39. init();
  40. }
  41. function init(){
  42. oDiv.onmousedown = fnDown;
  43. }
  44. function fnDown(ev){
  45. var ev = ev || window.event;
  46. disX = ev.clientX - oDiv.offsetLeft;
  47. disY = ev.clientY - oDiv.offsetTop;
  48. document.onmousemove = fnMove;
  49. document.onmouseup = fnUp;
  50. return false;
  51. }
  52. function fnMove(ev){
  53. var ev = ev || window.event;
  54. oDiv.style.left = ev.clientX - disX + 'px';
  55. oDiv.style.top = ev.clientY - disY + 'px';
  56. }
  57. function fnUp(){
  58. document.onmousemove = null;
  59. document.onmouseup = null;
  60. }
  61. */
  62. //改成面向对象
  63. window.onload = function(){
  64. var d1 = new Drag('div1');
  65. d1.init();
  66. }
  67. function Drag(id){
  68. this.oDiv = document.getElementById(id);
  69. this.disX = 0;
  70. this.dixY = 0;
  71. }
  72. Drag.prototype.init = function(){
  73. var This = this;
  74. this.oDiv.onmousedown = function(ev){
  75. var ev = ev || window.event;
  76. This.fnDown(ev);
  77. return false;
  78. };
  79. }
  80. Drag.prototype.fnDown = function(ev) {
  81. var ev = ev || window.event;
  82. var This = this;
  83. this.disX = ev.clientX - this.oDiv.offsetLeft;
  84. this.disY = ev.clientY - this.oDiv.offsetTop;
  85. document.onmousemove = function(ev){
  86. var ev = ev || window.event;
  87. This.fnMove(ev);
  88. };
  89. document.onmouseup = this.fnUp;
  90. }
  91. Drag.prototype.fnMove = function(ev){
  92. this.oDiv.style.left = ev.clientX - this.disX + 'px';
  93. this.oDiv.style.top = ev.clientY - this.disY + 'px';
  94. }
  95. Drag.prototype.fnUp = function(){
  96. document.onmousemove = null;
  97. document.onmouseup = null;
  98. }
  99. </script>
  100. </head>
  101. <body>
  102. <div id="div1"></div>
  103. </body>
  104. </html>

本课练习

  1. 为数组对象添加求和,最大值
  2. 为字符串对象添加判断是不是最后一个字母
  3. 面向对象的选项卡
  4. 给选项卡添加一个自动播放的方法
  5. 任意学过的效果改写成面向对象
  6. 面向对象的面试题

高级面向对象

包装对象

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. </style>
  8. <script>
  9. /*
  10. function Aaa(){
  11. this.name='小明';
  12. }
  13. Aaa.prototype.showName=function(){
  14. alert(this.name);
  15. }
  16. var a1 = new Aaa();
  17. a1.showName();
  18. var arr = new Array();
  19. arr.push();
  20. arr.sort();
  21. // 在js源码中:系统对象也是基于原型的程序
  22. function Array(){
  23. this.length = 0;
  24. }
  25. Array.prototype.push = function(){};
  26. Array.prototype.sort = function(){};
  27. */
  28. //尽量不要去修改或添加系统对象下面的方法和属性
  29. var arr = [1, 2, 3];
  30. //Arr.prototype.push = function(){}; //加上这句话,就修改了源码中的push方法,那么后面那一句中的4、5、6就添加不进去了
  31. Array.prototype.push = function(){ //自己写一个数组的push方法
  32. //this : 1, 2, 3
  33. //arguments: 4, 5, 6
  34. for(var i=0; i<arguments.length; i++){
  35. this[this.length] = arguments[i];
  36. }
  37. return this.length;
  38. }
  39. arr.push(4, 5, 6);
  40. alert(arr);
  41. </script>
  42. </head>
  43. <body>
  44. </body>
  45. </html>

给基本类型添加方法

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. </style>
  8. <script>
  9. /*
  10. var str = 'hello';
  11. alert( typeof str); //string
  12. str.charAt(0); //字符串为什么下面会有方法呢?
  13. str.indexOf('e');
  14. */
  15. //包装对象:基本类型都有自己对应的包装对象(String, Number, Boolean)(null和undefined没有包装对象)
  16. /*
  17. var str = new String('hello');
  18. alert(typeof str); //object
  19. alert(str.charAt(1)); //弹出e
  20. String.prototype.charAt = function(){}; //基本类型的方法都是放在它们的包装对象上
  21. */
  22. /*
  23. var str = 'hello'; //str是字符串
  24. str.charAt(0); //基本类型找到对应的包装对象类型,然后包装对象把所有的属性和方法给了基本类型,然后包装对象消失
  25. */
  26. //给基本类型添加对象的时候,就是把方法添加到基本类型对应的包装对象下面
  27. var str = 'hello';
  28. String.prototype.lastValue = function(){
  29. return this.charAt(this.length-1);
  30. };
  31. alert(str.lastValue()); //o
  32. var str1 = 'hello';
  33. str1.number = 10; //在str1的包装对象上创建了一个number,然后包装对象就消失了
  34. alert(str1.number); //undefined 再去调用这句话的时候,此时又重新创建了一个对象,这个对象与刚才那个对象不是同一个
  35. </script>
  36. </head>
  37. <body>
  38. </body>
  39. </html>

原型链

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象中的原型链</title>
  6. <style></style>
  7. <script>
  8. //原型链:实例对象与原型之间的连接叫作原型链
  9. //_proto_ (隐式连接)
  10. //原型链的最外层是Object.prototype
  11. function Aaa(){
  12. }
  13. Aaa.prototype.num = 10;
  14. var a1 = new Aaa();
  15. alert(a1.num); //10 a1现在它自己下面找,找不到这个num,然后又通过原型链到了Aaa.prototype,到它下面去找,最终找到了num
  16. function Bbb(){
  17. this.num = 20;
  18. }
  19. Bbb.prototype.num = 10;
  20. var b1 = new Bbb();
  21. alert(b1.num); //20 简单来讲,实例上的方法的优先级高于原型上的方法;本质上来讲,是从b1下面找num直接就找到了,于是就不需要再进一步通过原型链去找到Bbb.prototype上的num了。
  22. function Ccc(){};
  23. var c1 = new Ccc();
  24. Object.prototype.num = 30; //弹出30 c1下找不到num;顺着原型链找到Ccc也找不到num,继续顺着原型链往上找,找到Object.prototype,找到了num
  25. alert(c1.num);
  26. </script>
  27. </head>
  28. <body>
  29. </body>
  30. </html>

面向对象的一些属性和方法

hasOwnProperty()

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象中的原型链</title>
  6. <style></style>
  7. <script>
  8. //hasOwnProperty: 看是不是对象自身下面的属性
  9. var arr = [];
  10. arr.num = 10;
  11. Array.prototype.num2 = 20;
  12. alert(arr.hasOwnProperty('num')); //true
  13. alert(arr.hasOwnProperty('num2')); //false
  14. alert(arr.hasOwnProperty == Object.prototype.hasOwnProperty); //true hasOwnProperty其实是Object.prototype下面的方法
  15. </script>
  16. </head>
  17. <body>
  18. </body>
  19. </html>

constructor

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象中的原型链</title>
  6. <style></style>
  7. <script>
  8. //constructor: 查看对象的构造函数
  9. function Aaa(){
  10. }
  11. var a1 = new Aaa();
  12. alert(a1.constructor); //function Aaa
  13. var arr = [];
  14. alert(arr.constructor == Array); //true
  15. /*
  16. 在写完一个构造函数之后
  17. function Aaa(){}
  18. 程序会自动添加一句话:
  19. Aaa.prototype.constructor = Aaa; //每一个函数都会有的,都是自动生成的
  20. 这时候new一个Aaa
  21. var a1 = new Aaa();
  22. alert(a1.constructor); //弹出Aaa
  23. 如果手动写一句:
  24. Aaa.prototype.constructor = Array;
  25. 那么再去弹a1.constructor的话,弹出的就是Array了。
  26. 而hasOwnProperty这个属性是添加在Object.prototype下面的,所以每个对象下面去查这个hasOwnProperty也都会有。但是hasOwnProperty这个方法不是在具体对象下面的,而都是沿着原型链找到Object.prototype身上找到的。跟constructor是不一样的。
  27. */
  28. function Bbb(){
  29. }
  30. Bbb.prototype.name = '小明';
  31. Bbb.prototype.age = 20;
  32. var b1 = new Bbb();
  33. alert(b1.constructor); //function Bbb()
  34. //下面这种写法就无意识地改变了c1的constructor,因为json直接赋值给了Ccc.prototype,而不是向上面那段代码是添加操作。那么原本系统自动生成的那句话Ccc.prototype.constructor = Ccc这句话就被覆盖掉了。然后通过c1.constructor去找的话,其实找的就是这个json所对应的constructor了。
  35. function Ccc(){
  36. }
  37. Ccc.prototype = {
  38. name: '小明',
  39. age: 20
  40. }
  41. var c1 = new Ccc();
  42. alert(c1.constructor); //function Object
  43. //为了避免上述问题,应该注意,用json简写的时候,要把constructor修正过来,如下:
  44. function Ddd(){
  45. }
  46. Ddd.prototype = {
  47. constructor: Ddd, //通过这一句来修正一下
  48. name: '小明',
  49. age: 20
  50. }
  51. var d1 = new Ddd();
  52. alert(d1.constructor); //Ddd
  53. </script>
  54. </head>
  55. <body>
  56. </body>
  57. </html>

for in循环,有些属性找不到

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>面向对象中的原型链</title>
  6. <style></style>
  7. <script>
  8. function Aaa(){
  9. }
  10. Aaa.prototype.name = 10;
  11. Aaa.prototype.constructor = Aaa;
  12. for (var attr in Aaa.prototype){
  13. alert(attr); //只能找到自己添加的,系统自动生成的比如constructor,for in循环是找不到的
  14. }
  15. </script>
  16. </head>
  17. <body>
  18. </body>
  19. </html>

instanceof

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>instanceof()</title>
  6. <style></style>
  7. <script>
  8. // instanceof: 对象与构造函数在原型链上是否有关系
  9. function Aaa(){
  10. }
  11. var a1 = new Aaa();
  12. alert(a1 instanceof Aaa); //true 看a1是否与Aaa在同一个原型链上
  13. alert(a1 instanceof Array); //false
  14. alert(a1 instanceof Object); //true
  15. </script>
  16. </head>
  17. <body>
  18. </body>
  19. </html>

toString()

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>toString()</title>
  6. <style></style>
  7. <script>
  8. // toString():
  9. // 位置:系统对象下面都是自带的;自己写的对象都是通过原型链找Object下面的
  10. // 作用:把对象转成字符串
  11. var arr = [];
  12. alert(arr.toString); //找得到
  13. alert(arr.toString == Object.prototype.toString); //false 系统对象下面的toString不在Object原型上
  14. function Aaa(){
  15. }
  16. var a1 = new Aaa();
  17. alert(a1.toString); //找得到
  18. alert(a1.toString == Object.prototype.toString); //true 构造函数生成的对象的toString方法在Object原型上
  19. var arr = [1, 2, 3];
  20. alert(typeof arr.toString()); //string
  21. alert(arr.toString()); //"1, 2, 3"
  22. //因为知道toString在哪儿了,所以可以手动修改toString方法
  23. Array.prototype.toString = function(){
  24. return this.join('+');
  25. }
  26. alert(arr.toString()); //"1+2+3"
  27. var num = 255;
  28. alert(num.toString(16)); //"ff" 将255转成16进制
  29. //利用toString进行类型判断(用constructor和instanceof也都可以进行类型判断)。推荐toString来判断例如数组的类型
  30. var arr = []
  31. var date = new Date;
  32. var json = {}
  33. var reg = new RegExp;
  34. var n = null;
  35. alert(Object.prototype.toString.call(arr)); //[object Array]
  36. alert(Object.prototype.toString.call(date)); //[object Date]
  37. alert(Object.prototype.toString.call(json)); //[object Object]
  38. alert(Object.prototype.toString.call(reg)); //[object RegExp]
  39. alert(Object.prototype.toString.call(n)); //[object Null]
  40. //判断类型时直接进行比较就可以了,例如判断arr是否是数组:
  41. alert(Object.prototype.toString.call(arr) == '[object Array]'); //true
  42. //举例说明用instanceof和constructor来判断数组失效,但是toString依然有效的例子
  43. window.onload = function(){
  44. var oF = document.createElement('iframe');
  45. document.body.appendChild(oF);
  46. var ifArray = window.frames[0].Array; //ifArray就是iframe里面的数组
  47. var arr = new ifArray(); //ifArray就是iframe里面的数组 这时候跨页面了
  48. alert(arr.constructor == Array); //false constructor判断iframe下面的数组失效
  49. alert(arr instanceof Array); //false 判断失效
  50. alert(Object.prototype.toString.call(arr) == '[object Array]'); //true 判断依然有效
  51. }
  52. </script>
  53. </head>
  54. <body>
  55. </body>
  56. </html>

对象的继承

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>继承</title>
  6. <style></style>
  7. <script>
  8. // 继承:子类不影响父类;子类可以继承父类的一些功能(实现代码复用)
  9. function CreatePerson(name, sex){ //父类
  10. this.name = name;
  11. this.sex = sex;
  12. }
  13. CreatePerson.prototype.showName = function(){
  14. alert(this.name);
  15. }
  16. var p1 = new CreatePerson('小明', '男');
  17. p1.showName();
  18. //属性的继承:调用父类的构造函数 用call改this指向
  19. //方法的继承:用for in循环
  20. function CreateStar(name, sex, job){ //子类
  21. // this.name = name;
  22. // this.sex = sex;
  23. CreatePerson.call(this, name, sex); //调用父类构造函数 需要修改指向
  24. this.job = job;
  25. }
  26. /*
  27. CreateStar.prototype = CreatePerson.prototype; //将父类的原型赋给子类,那么子类就获得了父类下所有的属性值,实现了方法的继承 但是这里有对象的引用问题,造成互相干涉
  28. 例如:
  29. CreateStar.prototype.showJob = function(){}
  30. 上面子类的原型添加的方法,那么父类CreatePerson.prototype下面也有了showJob的方法
  31. */
  32. //方法的继承应该用for in循环,将父类的所有属性拷贝给子类,这叫作“拷贝继承”。jQuery也是采用拷贝继承extend
  33. function extend(obj1, obj2){
  34. for(var attr in obj2){
  35. obj1[attr] = obj2[attr];
  36. }
  37. }
  38. extend(CreateStar.prototype, CreatePerson.prototype )
  39. var p2 = new CreateStar('黄晓明', '男', '演员')
  40. p2.showName();
  41. </script>
  42. </head>
  43. <body>
  44. </body>
  45. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>继承</title>
  6. <style></style>
  7. <script>
  8. var a = {
  9. name: '小明'
  10. };
  11. //var b = a;
  12. // var b = {};
  13. // for(var attr in a){
  14. // b[attr] = a[attr];
  15. // }
  16. // b.name = "小强";
  17. // alert(a.name);
  18. //将对象属性的拷贝封装成一个函数
  19. function extend(obj1, obj2){
  20. for(var attr in obj2){
  21. obj1[attr] = obj2[attr];
  22. }
  23. }
  24. var b = {};
  25. extend(b, a);
  26. b.name = '小强';
  27. alert(b.name);
  28. alert(a.name);
  29. </script>
  30. </head>
  31. <body>
  32. </body>
  33. </html>
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>继承</title>
  6. <style></style>
  7. <script>
  8. var a = [1, 2, 3];
  9. var b = a;
  10. // b.push(4); //修改 a、b之间引用链条存在
  11. // alert(a); //1, 2, 3, 4 a被b影响了
  12. b = [1, 2, 3, 4]; //重新赋值,内存中这个b又重新生成了。a和b之间这个引用的链条已经断开,a、b没有关系
  13. alert(a); //1, 2, 3 a未被影响
  14. //在for in循环中,子类原型的方法也直接等于了父类原型的方法,因为方法是函数,也是个对象,为什么这种“对象 = 对象”没有互相干涉呢?这是因为函数有些特殊,不能被修改,只能被重新赋值
  15. </script>
  16. </head>
  17. <body>
  18. </body>
  19. </html>

继承的拖拽

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #div1 {width: 100px; height: 100px; background: red; position: absolute;}
  8. #div2 {width: 100px; height: 100px; background: yellow; position: absolute; left: 100px;}
  9. </style>
  10. <script src="jquery-1.11.1.js"></script>
  11. <script>
  12. window.onload = function(){
  13. var d1 = new Drag('div1');
  14. d1.init();
  15. var d2 = new ChildDrag('div2');
  16. d2.init();
  17. }
  18. //父类的面向对象的拖拽开始
  19. function Drag(id){ //父类
  20. this.obj = document.getElementById(id);
  21. this.disX = 0;
  22. this.disY = 0;
  23. }
  24. Drag.prototype.init = function(){
  25. var This = this;
  26. this.obj.onmousedown = function(ev){
  27. var ev = ev || window.event;
  28. This.fnDown(ev);
  29. document.onmousemove = function(ev){
  30. var ev = ev || window.event;
  31. This.fnMove(ev);
  32. }
  33. document.onmouseup = function(){
  34. This.fnUp();
  35. }
  36. return false;
  37. }
  38. }
  39. Drag.prototype.fnDown = function(ev){
  40. this.disX = ev.clientX - this.obj.offsetLeft;
  41. this.disY = ev.clientY - this.obj.offsetTop;
  42. }
  43. Drag.prototype.fnMove = function(ev){
  44. this.obj.style.left = ev.clientX - this.disX + 'px';
  45. this.obj.style.top = ev.clientY - this.disY + 'px';
  46. }
  47. Drag.prototype.fnUp = function(){
  48. document.onmousemove = null;
  49. document.onmouseup = null;
  50. }
  51. //父类的面向对象的拖拽结束
  52. //子类继承父类开始
  53. function ChildDrag(id){ //子类
  54. Drag.call(this, id);
  55. }
  56. extend(ChildDrag.prototype, Drag.prototype);
  57. //通过改变ChildDrap原型下的fnMove,给子类添加了限制拖拽时,元素超出可视区左右边界的功能
  58. ChildDrag.prototype.fnMove = function(ev){
  59. var L = ev.clientX - this.disX;
  60. var T = ev.clientY - this.disY;
  61. if(L < 0){
  62. L = 0;
  63. } else if (L > document.documentElement.clientWidth - this.obj.offsetWidth){
  64. L = document.documentElement.clientWidth - this.obj.offsetWidth;
  65. }
  66. this.obj.style.left = L + 'px';
  67. this.obj.style.top = T + 'px';
  68. }
  69. function extend(obj1, obj2){
  70. for(var attr in obj2){
  71. obj1[attr] = obj2[attr];
  72. }
  73. }
  74. //子类继承父类结束
  75. </script>
  76. </head>
  77. <body>
  78. <div id="div1"></div>
  79. <div id="div2"></div>
  80. </body>
  81. </html>

类式继承

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. </style>
  8. <script>
  9. //类:JS是没有类的概念的,可以把JS中的构造函数看做是类
  10. //要做属性和方法继承的时候,要分开继承
  11. function Aaa(){ //父类
  12. this.name = '小明';
  13. this.arr = [1, 2, 3];
  14. }
  15. Aaa.prototype.showName = function(){
  16. alert(this.name);
  17. }
  18. function Bbb(){ //子类
  19. }
  20. Bbb.prototype = new Aaa(); //这句话就是类式继承
  21. //只写上面一句话是有问题的,修改了constructor指向。
  22. //Bbb.prototype.constructor = Bbb; //修正指向问题
  23. var b1 = new Bbb();
  24. b1.showName();
  25. alert(b1.name);
  26. alert(b1.constructor); //弹出的并不是Bbb,而是Aaa。只有写了上面修正指向的那句话,这里才会变成Bbb
  27. //真正规范的类式继承要用下面几句话:
  28. // function Bbb(){ //这里只继承了属性
  29. // Aaa.call(this)
  30. // }
  31. //var F = function(){}; //创建一个空的构造函数
  32. //F.prototype = Aaa.prototype;
  33. //Bbb.prototype = new F(); //这里只继承了方法
  34. //Bbb.prototype.constructor = Bbb;
  35. b1.arr.push(4);
  36. var b2 = new Bbb();
  37. alert(b2.arr); //[1, 2, 3, 4] 这里看到上面的b1.arr.push(4)影响到了这里 要避免这种问题,应该用上面的类式继承的规范写法才行
  38. </script>
  39. </head>
  40. <body>
  41. </body>
  42. </html>

原型继承

  1. <head>
  2. <meta charset="UTF-8">
  3. <title>原型继承</title>
  4. <style>
  5. </style>
  6. <script>
  7. var a = {
  8. name: '小明'
  9. }
  10. var b = cloneObj(a); //让b继承a
  11. b.name = '小强'; //这一句不会更改a的name,因为这一句在b的下面又新建了一个属性name,值为“小强”
  12. alert(b.name); //小强
  13. alert(a.name); //小明
  14. function cloneObj(obj){
  15. var F = function(){};
  16. F.prototype = obj;
  17. return new F();
  18. }
  19. </script>
  20. </head>
  21. <body>
  22. </body>
  23. </html>

组件开发

如何配置参数和默认参数

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>组件开发中的参数问题</title>
  6. <script>
  7. //用json来解决参数数量问题
  8. function show(opt){
  9. }
  10. show({
  11. id: 'div1',
  12. toDown: function(){},
  13. toUp: function(){}
  14. });
  15. //用下面的方法解决参数顺序问题
  16. var a = { //配置参数
  17. //name: '小明'
  18. name: '小明'
  19. }
  20. var b = { //默认参数
  21. name: '小强'
  22. }
  23. extend(b, a); //当有配置的时候,走配置,没有配置的时候,走默认
  24. alert(b.name);
  25. function extend(obj1, obj2){
  26. for(var attr in obj2){
  27. obj1[attr] = obj2[attr];
  28. }
  29. }
  30. </script>
  31. </head>
  32. <body>
  33. </body>
  34. </html>

拖拽的组件开发

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #div1 {width: 100px; height: 100px; background: red; position: absolute;}
  8. #div2 {width: 100px; height: 100px; background: yellow; position: absolute; left: 100px;}
  9. #div3 {width: 100px; height: 100px; background: blue; position: absolute; left: 200px;}
  10. #div4 {width: 100px; height: 100px; background: green; position: absolute; left: 300px;}
  11. </style>
  12. <script src="jquery-1.11.1.js"></script>
  13. <script>
  14. /*
  15. 组件开发:像兄弟之间的关系(代码复用的一种形式)
  16. */
  17. window.onload = function(){
  18. var d1 = new Drag();
  19. d1.init('div1');
  20. var d2 = new Drag();
  21. d2.init('div2', { //配置参数
  22. toDown: function(){
  23. document.title = 'hello';
  24. }
  25. });
  26. var d3 = new Drag();
  27. d3.init('div3', { //配置参数
  28. toDown: function(){
  29. document.title = '妙味';
  30. },
  31. toUp: function(){
  32. document.title = '课堂';
  33. }
  34. });
  35. var d4 = new Drag();
  36. d4.init('div4', { //配置参数
  37. toUp: function(){
  38. document.title = 'byebye';
  39. }
  40. });
  41. }
  42. function Drag(){
  43. this.obj = null;
  44. this.disX = 0;
  45. this.disY = 0;
  46. this.settings = { //默认参数
  47. //id不应该属于配置参数当中,它属于必填项
  48. toDown: function(){},
  49. toUp: function(){}
  50. }
  51. }
  52. Drag.prototype.init = function(id, opt){
  53. var This = this;
  54. this.obj = document.getElementById(id);
  55. extend(this.settings, opt); //用配置覆盖默认
  56. this.obj.onmousedown = function(ev){
  57. var ev = ev || window.event;
  58. This.fnDown(ev);
  59. This.settings.toDown();
  60. document.onmousemove = function(ev){
  61. var ev = ev || window.event;
  62. This.fnMove(ev);
  63. }
  64. document.onmouseup = function(){
  65. This.fnUp();
  66. This.settings.toUp();
  67. }
  68. return false;
  69. }
  70. }
  71. Drag.prototype.fnDown = function(ev){
  72. this.disX = ev.clientX - this.obj.offsetLeft;
  73. this.disY = ev.clientY - this.obj.offsetTop;
  74. }
  75. Drag.prototype.fnMove = function(ev){
  76. this.obj.style.left = ev.clientX - this.disX + 'px';
  77. this.obj.style.top = ev.clientY - this.disY + 'px';
  78. }
  79. Drag.prototype.fnUp = function(){
  80. document.onmousemove = null;
  81. document.onmouseup = null;
  82. }
  83. function extend(obj1, obj2){
  84. for(var attr in obj2){
  85. obj1[attr] = obj2[attr];
  86. }
  87. }
  88. </script>
  89. </head>
  90. <body>
  91. <div id="div1"></div> <!-- 红色方块是老大 -->
  92. <div id="div2"></div> <!-- 黄色方块是老二 黄色的按下之后title有一个变化 -->
  93. <div id="div3"></div> <!-- 老三 按下title变化,抬起title变化 -->
  94. <div id="div4"></div> <!-- 老四 鼠标抬起时title有变化 -->
  95. </body>
  96. </html>

弹窗的组件开发

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>弹窗的组件开发</title>
  6. <style>
  7. * {margin : 0; padding; 0}
  8. .login {background: white; border: 1px #000 solid; position: absolute; left: 0; top: 0; z-index: 2;}
  9. .title {height: 30px; background: gray; color: white;}
  10. .title .close {float: right;}
  11. #mask {width: 500px; height: 500px; background: black; filter: alpha(oapcity=50); opacity: 0.5; position: absolute; left: 0; top: 0; z-index: 1;}
  12. </style>
  13. <script>
  14. window.onload = function(){
  15. var aInput = document.getElementsByTagName('input');
  16. aInput[0].onclick = function(){
  17. var d1 = new Dialog();
  18. d1.init({//配置参数
  19. iNow: 0,
  20. title: '登陆'
  21. });
  22. }
  23. aInput[1].onclick = function(){
  24. var d2 = new Dialog();
  25. d2.init({//配置参数
  26. iNow: 1,
  27. w : 100,
  28. h : 400,
  29. dir: 'right',
  30. title: '公告'
  31. });
  32. }
  33. aInput[2].onclick = function(){
  34. var d3 = new Dialog();
  35. d3.init({//配置参数
  36. iNow: 2,
  37. mask: true
  38. });
  39. }
  40. }
  41. function Dialog(){
  42. this.oLogin = null;
  43. this.settings = { //默认参数
  44. w: 300,
  45. h: 300,
  46. dir: 'center',
  47. title: '',
  48. mask: false
  49. }
  50. }
  51. Dialog.prototype.json = {}; //防止添加多个弹窗
  52. Dialog.prototype.init = function(opt){
  53. extend(this.settings, opt);
  54. if(this.json[opt.iNow] == undefined){
  55. this.json[opt.iNow] = true;
  56. }
  57. if(this.json[opt.iNow]){ //防止添加多个弹窗
  58. this.create();
  59. this.fnClose();
  60. if(this.settings.mask){
  61. this.createMask();
  62. }
  63. this.json[opt.iNow] = false;
  64. }
  65. }
  66. Dialog.prototype.create = function(){
  67. this.oLogin = document.createElement('div');
  68. this.oLogin.className = 'login';
  69. this.oLogin.innerHTML = '<div class="title"><span>' + this.settings.title + '</span><span class="close">X</span></div><div class="content"></div>';
  70. document.body.appendChild(this.oLogin);
  71. this.setData();
  72. }
  73. Dialog.prototype.setData = function(){
  74. this.oLogin.style.width = this.settings.w + 'px';
  75. this.oLogin.style.height = this.settings.h + 'px';
  76. if(this.settings.dir == 'center'){
  77. this.oLogin.style.left = (viewWidth() - this.oLogin.offsetWidth)/2 + 'px';
  78. this.oLogin.style.top = (viewHeight() - this.oLogin.offsetHeight)/2 + 'px';
  79. } else if (this.settings.dir == 'right'){
  80. this.oLogin.style.left = (viewWidth() - this.oLogin.offsetWidth) + 'px';
  81. this.oLogin.style.top = (viewHeight() - this.oLogin.offsetHeight) + 'px';
  82. }
  83. }
  84. Dialog.prototype.fnClose = function(){
  85. var oClose = this.oLogin.getElementsByTagName('span')[1];
  86. var This = this;
  87. oClose.onclick = function(){
  88. document.body.removeChild(This.oLogin);
  89. if(This.settings.mask){
  90. document.body.removeChild(This.oMask);
  91. }
  92. This.json[This.settings.iNow] = true;
  93. }
  94. }
  95. Dialog.prototype.createMask = function(){
  96. var oMask = document.createElement('div');
  97. oMask.id = 'mask';
  98. document.body.appendChild(oMask);
  99. this.oMask = oMask;
  100. oMask.style.width = viewWidth() + 'px';
  101. oMask.style.height = viewHeight() + 'px';
  102. }
  103. function extend(obj1, obj2){
  104. for(var attr in obj2){
  105. obj1[attr] = obj2[attr];
  106. }
  107. }
  108. function viewWidth(){
  109. return document.documentElement.clientWidth;
  110. }
  111. function viewHeight(){
  112. return document.documentElement.clientHeight;
  113. }
  114. </script>
  115. </head>
  116. <body>
  117. <input type="button" value="1">
  118. <input type="button" value="2">
  119. <input type="button" value="3">
  120. <!-- <div class="login">
  121. <div class="title">
  122. <span>标题</span><span class="close">X</span>
  123. </div>
  124. <div class="content"></div>
  125. </div> -->
  126. <!-- <div id="mask"></div> -->
  127. </body>
  128. </html>

理解自定义事件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>自定义事件</title>
  6. <script>
  7. // 自定义事件:主要是跟函数有关系,让函数能够具备事件的某些特性
  8. // 三个人都针对show来添加功能。都添加到一个地方会乱,于是三个人分开来写
  9. /*
  10. function show(){
  11. alert(1); //第一个人写
  12. }
  13. function show(){
  14. alert(2); //第二个人写
  15. }
  16. function show(){
  17. alert(3); //第三个人写
  18. }
  19. show(); //只能执行第三个人写的,因为函数不能修改只能覆盖
  20. */
  21. //看看是否能让函数具备事件的特性,多人写的可以绑定上去,就解决了多人协作的问题。原理就如以下情形。当然以下代码不是添加自定义事件的代码,只是为了方便理解:
  22. /*
  23. window.addEventListener('show', function(){
  24. alert(1); //第一个人写的
  25. }, false);
  26. window.addEventListener('show', function(){
  27. alert(2); //第二个人写的
  28. }, false);
  29. window.addEventListener('show', function(){
  30. alert(3); //第三个人写的
  31. }, false);
  32. show(); //主动触发自定义事件
  33. */
  34. </script>
  35. </head>
  36. <body>
  37. </body>
  38. </html>

用原生js实现自定义事件

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>自定义事件</title>
  6. <script>
  7. //自定义事件重点在于将函数和元素以及事件名称建立关系,在执行某个函数的时候,主动触发某个事件名称下面相关的所有函数
  8. window.onload = function(){
  9. var oDiv = document.getElementById('div1');
  10. var oSpan = document.getElementById('span1');
  11. bindEvent(oDiv, 'click', function(){
  12. alert(1);
  13. })
  14. bindEvent(oDiv, 'click', function(){
  15. alert(2);
  16. })
  17. bindEvent(oSpan, 'show', function(){ //这里的show就是个自定义事件
  18. alert(3);
  19. })
  20. bindEvent(oSpan, 'show', function(){ //这里的show就是个自定义事件
  21. alert(4);
  22. })
  23. bindEvent(oSpan, 'hide', function(){ //这里的show就是个自定义事件
  24. alert(5);
  25. })
  26. fireEvent(oSpan, 'show'); //主动触发,弹出3, 4
  27. fireEvent(oDiv, 'click'); //主动触发,弹出1, 2
  28. }
  29. function bindEvent(obj, events, fn){
  30. //fn: 看作一本书 《西游记》
  31. //obj: 相当于图书馆的楼层 文学楼
  32. //events: 相当于书架 古典文学书架
  33. obj.listeners = obj.listeners || {}; //先找到楼层,没有楼层就创建楼层
  34. obj.listeners[events] = obj.listeners[events] || []; //再找到书架,没有书架就创建书架
  35. obj.listeners[events].push(fn); //把fn这本书放到书架上
  36. /* 通过以上的方式,将obj,events和fn建立了关系*/
  37. if(obj.addEventListener){
  38. obj.addEventListener(events, fn, false);
  39. } else {
  40. obj.attachEvent('on' + events, fn);
  41. }
  42. }
  43. function fireEvent(obj, events){ //主动触发自定义事件
  44. for(var i=0; i<obj.listeners[events].length; i++){
  45. obj.listeners[events][i]();
  46. }
  47. }
  48. </script>
  49. </head>
  50. <body>
  51. <div id="div1">div</div>
  52. <span id="span1">span</span>
  53. </body>
  54. </html>

配置、方法、自定义事件分离——正规组件的写法——基于拖拽的组件进行的修改

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>自定义事件的拖拽组件</title>
  6. <style>
  7. #div1 {width: 100px; height: 100px; background: red; position: absolute;}
  8. #div2 {width: 100px; height: 100px; background: yellow; position: absolute; left: 100px;}
  9. #div3 {width: 100px; height: 100px; background: blue; position: absolute; left: 200px;}
  10. #div4 {width: 100px; height: 100px; background: green; position: absolute; left: 300px;}
  11. </style>
  12. <script src="jquery-1.11.1.js"></script>
  13. <script>
  14. window.onload = function(){
  15. var d1 = new Drag();
  16. d1.init('div1');
  17. var d2 = new Drag();
  18. d2.init('div2');
  19. bindEvent(d2, 'toDown', function(){
  20. document.title = 'hello';
  21. });
  22. bindEvent(d2, 'toDown', function(){ //新来的一个同事扩展d2的toDown事件的时候,更容易
  23. document.body.style.background = 'black';
  24. })
  25. var d3 = new Drag();
  26. d3.init('div3');
  27. bindEvent(d3, 'toDown', function(){
  28. document.title = '妙味';
  29. })
  30. bindEvent(d3, 'toUp', function(){
  31. document.title = '课堂';
  32. })
  33. var d4 = new Drag();
  34. d4.init('div4');
  35. bindEvent(d4, 'toUp', function(){
  36. document.title = 'byebye';
  37. })
  38. }
  39. function Drag(){
  40. this.obj = null;
  41. this.disX = 0;
  42. this.disY = 0;
  43. this.settings = {
  44. }
  45. }
  46. Drag.prototype.init = function(id, opt){
  47. var This = this;
  48. this.obj = document.getElementById(id);
  49. extend(this.settings, opt);
  50. this.obj.onmousedown = function(ev){
  51. var ev = ev || window.event;
  52. This.fnDown(ev);
  53. fireEvent(This, 'toDown');
  54. document.onmousemove = function(ev){
  55. var ev = ev || window.event;
  56. This.fnMove(ev);
  57. }
  58. document.onmouseup = function(){
  59. This.fnUp();
  60. fireEvent(This, 'toUp');
  61. }
  62. return false;
  63. }
  64. }
  65. Drag.prototype.fnDown = function(ev){
  66. this.disX = ev.clientX - this.obj.offsetLeft;
  67. this.disY = ev.clientY - this.obj.offsetTop;
  68. }
  69. Drag.prototype.fnMove = function(ev){
  70. this.obj.style.left = ev.clientX - this.disX + 'px';
  71. this.obj.style.top = ev.clientY - this.disY + 'px';
  72. }
  73. Drag.prototype.fnUp = function(){
  74. document.onmousemove = null;
  75. document.onmouseup = null;
  76. }
  77. function extend(obj1, obj2){
  78. for(var attr in obj2){
  79. obj1[attr] = obj2[attr];
  80. }
  81. }
  82. function bindEvent(obj, events, fn){
  83. obj.listeners = obj.listeners || {};
  84. obj.listeners[events] = obj.listeners[events] || [];
  85. obj.listeners[events].push(fn);
  86. if(obj.nodeType){ //如果传进来的是DOM元素的话,走着下面;如果传进来的不是DOM,是对象的话,就不走下面,只走上面了
  87. if(obj.addEventListener){
  88. obj.addEventListener(events, fn, false);
  89. } else {
  90. obj.attachEvent('on' + events, fn);
  91. }
  92. }
  93. }
  94. function fireEvent(obj, events){
  95. if(obj.listeners && obj.listeners[events]){
  96. for(var i=0; i<obj.listeners[events].length; i++){
  97. obj.listeners[events][i]();
  98. }
  99. }
  100. }
  101. </script>
  102. </head>
  103. <body>
  104. <div id="div1"></div>
  105. <div id="div2"></div>
  106. <div id="div3"></div>
  107. <div id="div4"></div>
  108. </body>
  109. </html>

**用JQ实现选项卡的组件开发

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>基于JQ的选项卡组件开发</title>
  6. <style>
  7. html, body {margin: 0; padding: 0;}
  8. #div1 div, #div2 div, #div3 div, #div4 div {width: 200px; height: 200px; border: 1px solid #000; display: none;}
  9. #div1 .active, #div2 .active, #div3 .active, #div4 .active {background: red;}
  10. </style>
  11. <script src="jquery-1.11.1.js"></script>
  12. <script>
  13. /*
  14. title: 基于JQ的选项卡组件
  15. Options:
  16. - event
  17. - delay
  18. Methods:
  19. - nowSel() - 设置开始的tab数
  20. - getContent() - 获取当前内容
  21. Events:
  22. - beforeClick 点击前触发
  23. - afterClick 点击后触发
  24. */
  25. // JQ中的主动触发:trigger()
  26. $(function(){
  27. var t1 = new Tab();
  28. t1.init('div1', {});
  29. var t2 = new Tab();
  30. t2.init('div2', {
  31. event: 'mouseover'
  32. });
  33. var t3 = new Tab();
  34. t3.init('div3', {
  35. event: 'mouseover',
  36. delay: 200
  37. });
  38. var t4 = new Tab();
  39. t4.init('div4', {});
  40. t4.nowSel(2);
  41. $('#input1').click(function(){
  42. alert(t4.getContent());
  43. })
  44. $(t4).on('beforeClick', function(){
  45. alert(t4.getContent());
  46. })
  47. $(t4).on('afterClick', function(){
  48. alert(t4.getContent());
  49. })
  50. })
  51. function Tab(){
  52. this.oParent = null;
  53. this.aInput = null;
  54. this.aDiv = null;
  55. this.iNow = 0;
  56. this.settings = { //默认参数
  57. event: 'click',
  58. delay: 0
  59. }
  60. }
  61. Tab.prototype.init = function(oParent, opt){
  62. $.extend(this.settings, opt);
  63. this.oParent = $('#' + oParent);
  64. this.aInput = this.oParent.find('input');
  65. this.aDiv = this.oParent.find('div');
  66. this.change();
  67. }
  68. Tab.prototype.change = function(){
  69. var This = this;
  70. var timer = null;
  71. this.aInput.on(this.settings.event, function(){
  72. if(This.settings.event == 'mouseover' && This.settings.delay){
  73. var _this = this;
  74. timer = setTimeout(function(){
  75. show(_this);
  76. }, This.settings.delay)
  77. } else {
  78. show(this);
  79. }
  80. }).mouseout(function(){
  81. clearTimeout(timer);
  82. });
  83. function show(obj){
  84. $(This).trigger('beforeClick');
  85. This.aInput.attr('class', '');
  86. This.aDiv.css('display', 'none');
  87. $(obj).attr('class', 'active');
  88. This.aDiv.eq($(obj).index()).css('display', 'block');
  89. This.iNow = $(obj).index();
  90. $(This).trigger('afterClick');
  91. }
  92. Tab.prototype.nowSel = function(index){
  93. this.aInput.attr('class', '');
  94. this.aDiv.css('display', 'none');
  95. this.aInput.eq(index).attr('class', 'active');
  96. this.aDiv.eq(index).css('display', 'block');
  97. this.iNow = index;
  98. }
  99. Tab.prototype.getContent = function(){
  100. return this.aDiv.eq(this.iNow).html();
  101. }
  102. }
  103. </script>
  104. </head>
  105. <body>
  106. <div id="div1">
  107. <input type="button" value="1" class="active">
  108. <input type="button" value="2">
  109. <input type="button" value="3">
  110. <div style="display: block">111111</div>
  111. <div>222222</div>
  112. <div>333333</div>
  113. </div>
  114. <div id="div2">
  115. <input type="button" value="1" class="active">
  116. <input type="button" value="2">
  117. <input type="button" value="3">
  118. <div style="display: block">111111</div>
  119. <div>222222</div>
  120. <div>333333</div>
  121. </div>
  122. <div id="div3">
  123. <input type="button" value="1" class="active">
  124. <input type="button" value="2">
  125. <input type="button" value="3">
  126. <div style="display: block">111111</div>
  127. <div>222222</div>
  128. <div>333333</div>
  129. </div>
  130. <div id="div4">
  131. <input type="button" value="1" class="active">
  132. <input type="button" value="2">
  133. <input type="button" value="3">
  134. <div style="display: block">111111</div>
  135. <div>222222</div>
  136. <div>333333</div>
  137. </div>
  138. <input type="button" value="点击" id="input1">
  139. </body>
  140. </html>

妙味综合案例

图片放大镜效果

子集影响父级的bug

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #div1 {width: 200px; height: 200px; background: red;}
  8. #div2 {width: 100px; height: 100px; background: yellow;}
  9. </style>
  10. <script>
  11. window.onload = function(){
  12. var oDiv = document.getElementById('div1');
  13. oDiv.onmouseover = function(){
  14. document.title += '1';
  15. }
  16. oDiv.onmouseout = function(){
  17. document.title += '2';
  18. }
  19. // 会发现鼠标移到黄色div上的时候,title部分会一下子出现21,这个2是从div1移到div2触发的,而1是通过div2冒泡到div1上触发的
  20. }
  21. </script>
  22. </head>
  23. <body>
  24. <div id="div1">
  25. <div id="div2"></div>
  26. </div>
  27. </body>
  28. </html>

上述问题的解决方式(1)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #div1 {width: 200px; height: 200px; background: red;}
  8. #div2 {width: 100px; height: 100px; background: yellow;}
  9. </style>
  10. <script>
  11. // 解决方案:
  12. // 1. js: 用onmouseener和onmouseleave事件替代onmouseover和onmouseout。onmouseenter和onmouseleave事件,子级不会影响到父级
  13. // 2. css
  14. window.onload = function(){
  15. var oDiv = document.getElementById('div1');
  16. oDiv.onmouseenter = function(){
  17. document.title += '1';
  18. }
  19. oDiv.onmouseleave = function(){
  20. document.title += '2';
  21. }
  22. }
  23. </script>
  24. </head>
  25. <body>
  26. <div id="div1">
  27. <div id="div2"></div>
  28. </div>
  29. </body>
  30. </html>

上述问题的解决方式(2)

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title></title>
  6. <style>
  7. #div1 {width: 200px; height: 200px; background: red;}
  8. #div2 {width: 100px; height: 100px; background: yellow;}
  9. </style>
  10. <script>
  11. // 解决方案:
  12. // 1. js: 用onmouseener和onmouseleave事件替代onmouseover和onmouseout。onmouseenter和onmouseleave事件,子级不会影响到父级
  13. // 上述两个事件有兼容性问题,但是兼容性问题不大,而且做兼容非常的麻烦 兼容方式如下:
  14. // 2. css
  15. window.onload = function(){
  16. var oDiv = document.getElementById('div1');
  17. oDiv.onmouseover = function(ev){
  18. var ev = ev || window.event;
  19. var a = this, b = ev.relatedTarget; //ev.relatedTarget是相对目标,可以理解为之前的目标
  20. /*
  21. 1. 从body移到div1:a - div1;b - body
  22. 2. 从div1移到div2:a - div1;b - div1
  23. 3. 从div2移到div1:a - div1;b - div2
  24. */
  25. if(!elContains(a, b) && a!=b){
  26. document.title += '1';
  27. }
  28. }
  29. oDiv.onmouseout = function(ev){
  30. var ev = ev || window.event;
  31. var a = this, b = ev.relatedTarget;
  32. if(!elContains(a, b) && a!=b){
  33. document.title += '2';
  34. }
  35. }
  36. }
  37. function elContains(a, b){ //判断两个元素是否是嵌套关系,看a是否包含b
  38. return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
  39. }
  40. </script>
  41. </head>
  42. <body>
  43. <div id="div1">
  44. <div id="div2"></div>
  45. </div>
  46. </body>
  47. </html>

图片的放大镜效果

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>图片放大镜效果</title>
  6. <style>
  7. html, body {margin: 0; padding: 0;}
  8. #div1 {width: 180px; height: 180px; overflow: hidden; position: relative;}
  9. #div1 span {width: 100px; height: 100px; background: yellow; opacity: 0.5; filter: alpha(opacity=50); position: absolute; left: 0; top: 0; display: none;}
  10. #mask {width: 180px; height: 180px; background: red; position: absolute; left: 0; top: 0; opacity: 0; filter: alpha(oapcity=0);}
  11. #div2 {width: 500px; height: 500px; position: absolute; left: 250px; top: 50px; overflow: hidden;}
  12. #div2 img {position: absolute; left: 0; top: 0;}
  13. </style>
  14. <script>
  15. //这里的onmouseover和onmouseout是用过CSS方式解决的问题,方法是添加了一个透明的层
  16. window.onload = function(){
  17. var oDiv = document.getElementById('div1');
  18. var oSpan = oDiv.getElementsByTagName('span')[0];
  19. var oDiv2 = document.getElementById('div2');
  20. var img2 = oDiv2.getElementsByTagName('img')[0];
  21. oDiv.onmouseenter = function(){
  22. oSpan.style.display = 'block';
  23. }
  24. oDiv.onmouseleave = function(){
  25. oSpan.style.display = 'none';
  26. }
  27. oDiv.onmousemove = function(ev){
  28. var ev = ev || window.event;
  29. var L = ev.clientX - oDiv.offsetLeft - oSpan.offsetWidth / 2;
  30. var T = ev.clientY - oDiv.offsetTop - oSpan.offsetHeight / 2;
  31. if(L < 0){
  32. L = 0;
  33. } else if (L > oDiv.offsetWidth - oSpan.offsetWidth){
  34. L = oDiv.offsetWidth - oSpan.offsetWidth;
  35. }
  36. if(T < 0){
  37. T = 0;
  38. } else if (T > oDiv.offsetHeight - oSpan.offsetHeight){
  39. T = oDiv.offsetHeight - oSpan.offsetHeight;
  40. }
  41. oSpan.style.left = L + 'px';
  42. oSpan.style.top = T + 'px';
  43. var scaleX = L / (oDiv.offsetWidth - oSpan.offsetWidth);
  44. var scaleY = T / (oDiv.offsetHeight - oSpan.offsetHeight);
  45. img2.style.left = -scaleX * (img2.offsetWidth - oDiv2.offsetWidth) + 'px';
  46. img2.style.top = -scaleY * (img2.offsetHeight - oDiv2.offsetHeight) + 'px';
  47. }
  48. }
  49. </script>
  50. </head>
  51. <body>
  52. <div id="div1">
  53. <img src="b2.jpg">
  54. <span></span>
  55. <div id="mask"></div>
  56. </div>
  57. <div id="div2">
  58. <img src="b1.jpg">
  59. </div>
  60. </body>
  61. </html>

苹果菜单

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>苹果菜单</title>
  6. <script>
  7. // Math.pow(3, 2); //3的平方
  8. // Math.pow(2, 3); //2的立方
  9. // Math.sqrt(9); //9的开方
  10. // Math.pow(9, 1/3); //9的开立方
  11. </script>
  12. <style>
  13. html, body {margin: 0; padding: 0;}
  14. #div1 img {width: 64px;}
  15. #div1 {width: 100%; height: auto; position: absolute; bottom: 0; text-align: center;}
  16. input {width: 300px;}
  17. </style>
  18. <script>
  19. window.onload = function(){
  20. var aInput = document.getElementsByTagName('input');
  21. var oDiv= document.getElementById('div1');
  22. var aImg = oDiv.getElementsByTagName('img');
  23. document.onmousemove = function(ev){
  24. var ev = ev || window.event;
  25. for(var i=0; i<aImg.length; i++){
  26. var x = aImg[i].offsetLeft + aImg[i].offsetWidth/2;
  27. var y = aImg[i].offsetTop + aImg[i].offsetHeight/2 + oDiv.offsetTop;
  28. var a = ev.clientX - x;
  29. var b = ev.clientY - y;
  30. var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
  31. var scale = 1 - c/300;
  32. if(scale < 0.5){
  33. scale = 0.5;
  34. }
  35. aInput[i].value = 'x轴:' + x + ',Y轴:' + y + ',与鼠标距离:' + c;
  36. aImg[i].style.width = scale * 128 + 'px';
  37. aImg[i].style.height = scale * 128 + 'px';
  38. }
  39. }
  40. }
  41. </script>
  42. </head>
  43. <body>
  44. <input type="text">
  45. <input type="text">
  46. <input type="text">
  47. <input type="text">
  48. <input type="text">
  49. <div id="div1">
  50. <img src="images/1.png">
  51. <img src="images/2.png">
  52. <img src="images/3.png">
  53. <img src="images/4.png">
  54. <img src="images/5.png">
  55. </div>
  56. </body>
  57. </html>

妙味照片墙效果

找最小值和位置

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>找最小值和位置</title>
  6. <script>
  7. var arr = [34, 71, 8, 934, 10];
  8. var value = 9999;
  9. var index = -1;
  10. for(var i=0; i<arr.length; i++){
  11. if(arr[i]< value){
  12. value = arr[i];
  13. index = i;
  14. }
  15. }
  16. alert('最小值:' + value + ',位置:' + index);
  17. </script>
  18. </head>
  19. <body>
  20. </body>
  21. </html>

照片墙的实现

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>妙味照片墙效果</title>
  6. <style>
  7. html, body {margin: 0; padding: 0;}
  8. #ul1 {width: 660px; position: relative; margin: 10px auto;}
  9. li {width: 200px; height: 150px; margin: 10px; float: left; list-style: none;}
  10. </style>
  11. <script>
  12. window.onload = function(){
  13. //布局转换,将浮动布局转成定位布局
  14. var aLi = document.getElementsByTagName('li');
  15. var izIndex = 2;
  16. var arr = [];
  17. var oInput = document.getElementById('input1');
  18. for(var i=0; i<aLi.length; i++){
  19. arr.push([aLi[i].offsetLeft, aLi[i].offsetTop]);
  20. }
  21. for(var i=0; i<aLi.length; i++){
  22. aLi[i].style.position = 'absolute';
  23. aLi[i].style.left = arr[i][0] + 'px';
  24. aLi[i].style.top = arr[i][1] + 'px';
  25. aLi[i].style.margin = 0; //去掉影响定位的值。例如margin、padding都已经算到left和top里面了,所以不需要再算进去
  26. }
  27. for(var i=0; i<aLi.length; i++){
  28. aLi[i].index = i;
  29. drag(aLi[i]);
  30. }
  31. oInput.onclick = function(){
  32. var randomArr = [0, 1, 2, 3, 4, 5, 6, 7, 8];
  33. randomArr.sort(function(n1, n2){
  34. return Math.random() - 0.5;
  35. })
  36. for(var i=0; i<aLi.length; i++){
  37. startMove(aLi[i], {left: arr[randomArr[i]][0], top: arr[randomArr[i]][1]});
  38. aLi[i].index = randomArr[i];
  39. }
  40. }
  41. function drag(obj){
  42. var disX = 0;
  43. var disY = 0;
  44. obj.onmousedown = function(ev){
  45. var ev = ev || window.event;
  46. obj.style.zIndex = izIndex ++;
  47. disX = ev.clientX - obj.offsetLeft;
  48. disY = ev.clientY - obj.offsetTop;
  49. document.onmousemove = function(ev){
  50. var ev = ev || window.event;
  51. obj.style.left = ev.clientX - disX + 'px';
  52. obj.style.top = ev.clientY - disY + 'px';
  53. // for(var i=0; i<aLi.length; i++){
  54. // if(pz(obj, aLi[i]) && obj != aLi[i]){
  55. // aLi[i].style.border = '2px solid red';
  56. // } else {
  57. // aLi[i].style.border = '';
  58. // }
  59. // }
  60. var nL = nearLi(obj);
  61. for(var i=0; i<aLi.length; i++){
  62. aLi[i].style.border = '';
  63. }
  64. if(nL){
  65. nL.style.border = '2px solid red';
  66. }
  67. }
  68. document.onmouseup = function(){
  69. document.onmousemove = null;
  70. document.onmouseup = null;
  71. var nL = nearLi(obj);
  72. var tmp = 0;
  73. if(nL){
  74. startMove(nL, {left: arr[obj.index][0], top: arr[obj.index][1]});
  75. startMove(obj, {left: arr[nL.index][0], top: arr[nL.index][1]});
  76. nL.style.border = '';
  77. tmp = obj.index;
  78. obj.index = nL.index;
  79. nL.index = tmp;
  80. } else {
  81. startMove(obj, {left: arr[obj.index][0], top: arr[obj.index][1]});
  82. }
  83. }
  84. return false;
  85. }
  86. }
  87. function nearLi(obj){
  88. var value = 9999;
  89. var index = -1;
  90. for(var i=0; i<aLi.length; i++){
  91. if(pz(obj, aLi[i]) && obj != aLi[i]){
  92. var c = jl(obj, aLi[i]);
  93. if(c<value){
  94. value = c;
  95. index = i;
  96. }
  97. }
  98. }
  99. if(index != -1){
  100. return aLi[index];
  101. } else {
  102. return false;
  103. }
  104. }
  105. function jl(obj1, obj2){
  106. var a = obj1.offsetLeft - obj2.offsetLeft;
  107. var b = obj1.offsetTop - obj2.offsetTop;
  108. return Math.sqrt(a*a + b*b);
  109. }
  110. function pz(obj1, obj2){
  111. var L1 = obj1.offsetLeft;
  112. var R1 = obj1.offsetLeft + obj1.offsetWidth;
  113. var T1 = obj1.offsetTop;
  114. var B1 = obj1.offsetTop + obj1.offsetHeight;
  115. var L2 = obj2.offsetLeft;
  116. var R2 = obj2.offsetLeft + obj2.offsetWidth;
  117. var T2 = obj2.offsetTop;
  118. var B2 = obj2.offsetTop + obj2.offsetHeight;
  119. if(R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2){ //碰不到的情况
  120. return false;
  121. } else { //其余都是碰到的情况
  122. return true;
  123. }
  124. }
  125. //以下是运动框架move.js的代码
  126. function css(obj, attr){
  127. if(obj.currentStyle){
  128. return obj.currentStyle[attr];
  129. } else {
  130. return getComputedStyle(obj, false)[attr];
  131. }
  132. }
  133. function startMove(obj, json, fn){
  134. clearInterval(obj.iTimer);
  135. var iCur = 0;
  136. var iSpeed = 0; //速度初始化
  137. obj.iTimer = setInterval(function(){
  138. var iBtn = true;
  139. for(var attr in json){
  140. var iTarget = json[attr];
  141. if(attr == 'opacity'){
  142. iCur = Math.round(css(obj, 'opacity') * 100);
  143. } else {
  144. iCur = parseInt(css(obj, attr));
  145. }
  146. iSpeed = (iTarget - iCur) / 8;
  147. iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed);
  148. if(iCur != iTarget){
  149. iBtn = false;
  150. if(attr == 'opacity'){
  151. obj.style.opacity = (iCur + iSpeed) / 100;
  152. obj.style.filter = 'alpha(opacity=' + (iCur + iSpeed) + ')';
  153. } else {
  154. obj.style[attr] = iCur + iSpeed + 'px';
  155. }
  156. }
  157. }
  158. if(iBtn){
  159. clearInterval(obj.iTimer);
  160. fn && fn.call(obj);
  161. }
  162. }, 30);
  163. }
  164. }
  165. </script>
  166. </head>
  167. <body>
  168. <input type="button" value="随机" id="input1">
  169. <ul id="ul1">
  170. <li><img src="photo/1.jpg"></li>
  171. <li><img src="photo/2.jpg"></li>
  172. <li><img src="photo/3.jpg"></li>
  173. <li><img src="photo/4.jpg"></li>
  174. <li><img src="photo/5.jpg"></li>
  175. <li><img src="photo/1.jpg"></li>
  176. <li><img src="photo/2.jpg"></li>
  177. <li><img src="photo/3.jpg"></li>
  178. <li><img src="photo/4.jpg"></li>
  179. </ul>
  180. </body>
  181. </html>
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注