你的位置:首页 > Java教程

[Java教程]jQuery 迭代器


在 叶小钗 的博客中看到一段关于遍历的代码

  var ajQuery = {};function dir(elem, dir, until) { var matched = [],  truncate = until !== undefined; while ((elem = elem[dir]) && elem.nodeType !== 9) {  if (elem.nodeType === 1) {   if (truncate) {    if (elem.nodeName.toLowerCase() == until || elem.className == until) {     break;    }   }   matched.push(elem);  } } return matched;}// 迭代器 jQuery.each({  parent: function(elem) {   var parent = elem.parentNode;   return parent && parent.nodeType !== 11 ? parent : null;  },  parents: function(elem) {   return dir(elem, "parentNode");  },  parentsUntil: function(elem, until) {   return dir(elem, "parentNode", until);  } }, function(name, fn) {  ajQuery[name] = function(until, selector) {   return fn(until, selector);  }; }); $("#test1").click(function() {  var item = $('.item-1');  alert(item.parent()[0])  alert(item.parents().length)  alert(item.parentsUntil('body').length) }) $("#test2").click(function() {  var item = document.querySelectorAll('.item-1')[0]  alert(ajQuery.parent(item))  alert(ajQuery.parents(item).length)  alert(ajQuery.parentsUntil(item, 'body').length) })


jQuery 中的each 不仅仅是用来遍历jQuery对象,还可以用来作为合并接口。

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

其中就利用了$.each(fn)的特性,jQuery 源码中 :

 each: function( obj, callback, args ){}

为obj 执行回调函数 callback。

 

里面的巧妙之处在于:

在为obj执行回调函数的时候,回调函数为新的对象 ajQuery{},绑定了新的属性(或方法)

function(name, fn) {  ajQuery[name] = function(until, selector) {   return fn(until, selector);  }; }

测试:

jQuery.each({  say: function(cont){   console.log(cont);  }}, function(name, fn) {  ajQuery[name] = function(until, selector) {   // 传递fn参数   return fn(until, selector);  };});

$("#test1").click(function() {
    ajQuery.say('oooooooo'); // oooooooo
})

 

 所以根据这个推论,总结each的原理:

1. 遍历obj对象;

2. 为callback传参;

3. 为每个obj[i],绑定callback

模拟写了个版本:

  o = {};  test = {    fn1: function(){},    fn2: function(){},    getDom: function(dom, fn){      var t = document.getElementById(dom)      return t.onclick = function(){        fn()      }     },    each: function(c, fn){      for(k in c){        fn.call(c[k],k,c[k]);      }      return c;    }  }  test.each({    say: function(cont){      console.log(cont)    },    walk: function(length){      console.log('walk '+length);    }  }, function(name, fn) {     o[name] = function(name){          return fn(name);      }  })

// 调用
test.getDom('btn', function(){
  o.say('aaaaa');
})