zoukankan      html  css  js  c++  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');
    })

     
  • 相关阅读:
    写代码时减少bug的八种方式
    ObjectiveC中对Url的参数进行编码
    iPhone中预览文档的三种方式
    GUID和INT两种数据类型做主键的比较
    通过FxCop来验证.NET编码规范
    一位程序员的一个LBS应用的想法
    iPhone中XML处理以及网络上的图片显示
    iOS开发之iPhone通过get和post方式请求asp.net webservice
    iOS开发之将XML转换成树
    objectivec内存管理基础
  • 原文地址:https://www.cnblogs.com/dongcheck/p/5784756.html
Copyright © 2011-2022 走看看