1-2 jQuery的遍历结构设计
本节编程练习不计算学习进度,请电脑登录imooc.com操作

jQuery的遍历结构设计

遍历的接口我们可以归为几大类:

1 祖先
2 同胞兄弟
3 后代
4 过滤

遍历的接口很多都是具有相似或者说是一类的处理功能,那么这种接口的设计我们不能就事论事的一个一个去实现,这样代码就会显得非常累赘也不容易维护,那么就这么几大类Query分了好几十API出来,丰富的接口可以让高层的设计更为简单。但是框架内部的却要简练。那么针对这种类似功能的接口,jQuery内部就会做更多的抽象处理了。

1.针对层级关系的处理,jQuery就抽出了一个dir的方法,用于根据传递的元素与词素的位置关系,查找指定的元素。

parent,parents,parentsUntil等方法如代码所示:

function dir(elem, dir, until) { 
   //参考右边代码  
   return matched;
}

2.我们在上半部的第一章中就提到过迭代器,迭代器是一个框架的重要设计。

我们经常需要提供一种方法顺序的用来处理聚合对象中各个元素,而又不暴露该对象的内部,这也是设计模式中的迭代器模式。

迭代器除了单纯的遍历,在jQuery内部的运用最多的就是接口的抽象合并,相同功能的代码功能合并处理:

jQuery.each({  
   parent: function(elem) {}, 
   parents: function(elem) {},  
   nextAll: function(elem) {},  
   prevAll: function(elem) {},  
   ................
}, function(name, fn) {  
   api[name] = function(until, selector){    
  //代码右图  
};
});

可以看出上面代码方法,针对相同的功能,节约了大量的代码空间。

任务

  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  5. <script src="http://img1.sycdn.imooc.com//down/540812440001e40e00000000.js" type="text/javascript"></script>
  6. <title></title>
  7. </head>
  8. <body>
  9.  
  10. <button id="test1">jQuery遍历祖先</button>
  11. <button id="test2">模拟遍历祖先</button>
  12.  
  13. <ul class="level-1">
  14. <li class="item-i">I</li>
  15. <li class="item-ii">II
  16. <ul class="level-2">
  17. <li class="item-a">A</li>
  18. <li class="item-b">B
  19. <ul class="level-3">
  20. <li class="item-1">1</li>
  21. <li class="item-2">2</li>
  22. <li class="item-3">3</li>
  23. </ul>
  24. </li>
  25. <li class="item-c">C</li>
  26. </ul>
  27. </li>
  28. <li class="item-iii">III</li>
  29. </ul>
  30.  
  31.  
  32. <script type="text/javascript">
  33.  
  34. var ajQuery = {};
  35.  
  36. function dir(elem, dir, until) {
  37. var matched = [],
  38. truncate = until !== undefined;
  39. while ((elem = elem[dir]) && elem.nodeType !== 9) {
  40. if (elem.nodeType === 1) {
  41. if (truncate) {
  42. if (elem.nodeName.toLowerCase() == until || elem.className == until) {
  43. break;
  44. }
  45. }
  46. matched.push(elem);
  47. }
  48. }
  49. return matched;
  50. }
  51.  
  52. jQuery.each({
  53. parent: function(elem) {
  54. var parent = elem.parentNode;
  55. return parent && parent.nodeType !== 11 ? parent : null;
  56. },
  57. parents: function(elem) {
  58. return dir(elem, "parentNode");
  59. },
  60. parentsUntil: function(elem, until) {
  61. return dir(elem, "parentNode", until);
  62. }
  63. }, function(name, fn) {
  64. ajQuery[name] = function(until, selector) {
  65. return fn(until, selector);
  66. };
  67. });
  68.  
  69.  
  70. $("#test1").click(function() {
  71. var item = $('.item-1');
  72. alert(item.parent()[0])
  73. alert(item.parents().length)
  74. alert(item.parentsUntil('body').length)
  75. })
  76.  
  77. $("#test2").click(function() {
  78. var item = document.querySelectorAll('.item-1')[0]
  79. alert(ajQuery.parent(item))
  80. alert(ajQuery.parents(item).length)
  81. alert(ajQuery.parentsUntil(item, 'body').length)
  82. })
  83.  
  84.  
  85. </script>
  86.  
  87. </body>
  88. </html>
下一节