这里要说的是迭代器,是一种思路而已,代码相对来不是最关键的,个人认为,最关键的部分是实现的思路
要求:
在一个网页中,将所有的 p 元素的内容进行替换,但是在特定的位置的 p 元素是要有差异的进行替换
涉及到两点:一个是范围(id=box),一个是替换对象(p元素),还有一个是具体的替换内容(执行方法,即执行函数),差异性替换:选择是可以变更的
1. 首先创建一个迭代器 Iterator
2.写执行函数
3.把迭代器用闭包包起来,同时把迭代器挂在window 对象上,这样外部就可以调用了
4.外部调用
代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>Document</title> 8 <style> 9 div, 10 p { 11 border: 1px solid red; 12 margin: 10px; 13 padding: 10px; 14 } 15 </style> 16 <script> 17 ; 18 (function(window, undefined) { 19 var Iterator = function(el, container) { 20 var Ocontainer = container && document.querySelector(container) || document, 21 // 获取需要提换的元素的全部 22 oNode = Ocontainer.querySelectorAll(el), 23 // 获取需要提换的元素的全部的长度 24 alength = oNode.length, 25 // 设置初始索引为0 26 index = 0, 27 // 改写splice 函数,因为这里是类数组,不能直接使用splice,要伪装成数组才能使用,改写就是伪装的过程 28 splice = [].splice; 29 // 写一个方法判断一个对象是否是数组 30 var isArray = function(obj) { 31 return Object.prototype.toString.call(obj) === "[object Array]"; 32 }; 33 // return 中的内容是需要返回的部分,当调用Iteratror 函数时,外部就可以调用return中的内容了 34 return { 35 // 获取第一个对象(元素)的方法 36 first: function() { 37 index = 0; 38 return oNode[index]; 39 }, 40 // 获取最后一个对象(元素)的方法 41 last: function() { 42 index = alength - 1; 43 return oNode[index]; 44 }, 45 // 获取上一个对象(元素)的方法 46 prev: function() { 47 if (--index > 0) { 48 return oNode[index]; 49 } else { 50 index = 0; 51 return null; 52 } 53 }, 54 // 获取下一个对象(元素)的方法 55 next: function() { 56 if (++index < alength) { 57 return oNode[index]; 58 } else { 59 index = alength - 1; 60 return null; 61 } 62 }, 63 // 获取确定的(索引为num)一个对象(元素)的方法 64 get: function(num) { 65 // 这里是一个赋值语句,不过要先执行三元表达式 66 index = num >= alength ? alength - 1 : num; 67 // 这里是一个短路表达值,也是一个赋值语句 68 (index < 0) && (index = 0); 69 return oNode[index]; 70 }, 71 // 遍历没一个项目对象,然后对执行fn 方法 72 eachItem: function(fn) { 73 // 这句话的意思是:获取除了第一个参数之外的所有参数,把它们装在一个数组里 74 var args = splice.call(arguments, 1); 75 for (var i = 0; i < alength; i++) { 76 // 执行fn 函数调用, 把this的指向改变了, this指向oNode[i] 77 fn.apply(oNode[i], args); 78 }; 79 }, 80 // 特殊处理函数 81 dealItem: function(n, fn) { 82 // 函数实体是fn, 83 // 把this指向改变了, this指向this.get(n) 即需要变化的元素对象 84 fn.apply(this.get(n), splice.call(arguments, 2)); 85 }, 86 // 具体执行的控制函数,在 MVC 结构中,这个相当于controller(负责分配事情的) ,而eachFn,和dealFn则相当于Modal(负责处理事情的) 87 exclusive: function(num, eachFn, dealFn) { 88 this.eachItem(eachFn); 89 if (isArray(num)) { 90 for (var i = 0, len = num.length; i < len; i++) { 91 this.dealItem(num[i], dealFn); 92 } 93 } else { 94 this.dealItem(num, dealFn); 95 } 96 } 97 } 98 }; 99 // 把Iterator 挂在window对象上,这样在外面才可以调用Iterator( 因为已经使用闭包包起来了,这是和外界唯一的交互接口) 100 window.Iterator = Iterator; 101 })(window, undefined); 102 </script> 103 </head> 104 <body> 105 <div id="box"> 106 <p>this is a test string</p> 107 <p>this is a test string</p> 108 <p>this is a test string</p> 109 <p>this is a test string</p> 110 <p>this is a test string</p> 111 <p>this is a test string</p> 112 <p>this is a test string</p> 113 <p>this is a test string</p> 114 </div> 115 <p>this is a test string</p> 116 <p>this is a test string</p> 117 </body> 118 </html>
js 调用:
1 <script> 2 window.onload = function() { 3 var oIter = Iterator('p', '#box'); 4 oIter.exclusive([1, 3], function() { 5 this.innerHTML = "这个是遍历的结果,在Id=box范围内每个元素都要替代"; 6 this.style.color = "#abc"; 7 }, function() { 8 this.innerHTML = "这个元素是要有差异的项目"; 9 this.style.color = "#730" 10 }); 11 } 12 </script>
运行结果:
调用函数:last(),dealItem()
js调用代码:
<script> window.onload = function() { var oIter = Iterator('p', '#box'); // 这里调用, 就涉及到 splice.call(arguments, 2) 参数调用了 oIter.last().style.backgroundColor = 'blue'; oIter.dealItem(2, function(bgC, txtC, txt) { this.style.backgroundColor = bgC; this.style.color = txtC; this.innerHTML = txt; }, 'red', 'white', '这里就是特殊处理的项目,涉及到arguments参数的调用了'); } </script>
运行结果: