zepto源码研究 - zepto.js-3 (常用的工具)

pluck:

/**
     * 根据是否存在此属性来获取当前集合,返回一组属性值
     * @param property
     * @returns {*}
     */
    pluck: function(property){
      return $.map(this, function(el){ return el[property] })
    },

获取zepto对象的父节点时用到

filtered:

/**
     *  过滤,返回处理结果为true的记录
     * @param selector
     * @returns {*}
     */
    filter: function(selector){
    /*
      if(!selector) return this;
    */
//this.not(selector)取到需要排除的集合,第二次再取反(这个时候this.not的参数就是一个集合了),得到想要的集合 if (isFunction(selector)) return this.not(this.not(selector)) //filter收集返回结果为true的记录 return $(filter.call(this, function(element){ //当element与selector匹配,则收集 return zepto.matches(element, selector) })) }, /** * 在元素集中过滤某些元素 * @param nodes * @param selector * @returns {*|HTMLElement} */ function filtered(nodes, selector) { return selector == null ? $(nodes) : $(nodes).filter(selector) }

 

parent:

   /**
     * 获取父元素
     * @param selector
     * @returns {*|HTMLElement}
     */
    parent: function(selector){
      return filtered(uniq(this.pluck('parentNode')), selector)
    }

 

$.map:

/**
   * 内部方法
   * 遍历对象/数组 在每个元素上执行回调,将回调的返回值放入一个新的数组返回
   * @param elements
   * @param callback
   * @returns {*}
   */
  $.map = function(elements, callback){
    var value, values = [], i, key
    //如果被遍历的数据是数组或者Zepto(伪数组)
    if (likeArray(elements))
      for (i = 0; i < elements.length; i++) {
        value = callback(elements[i], i)
     // 
if (value != null) values.push(value) } else //如果是对象 for (key in elements) { value = callback(elements[key], key) if (value != null) values.push(value) } return flatten(values) }

 

parents:

/**
     * 取得所有匹配的祖先元素
     * @param selector
     * @returns {*}
     */
    parents: function(selector){
      var ancestors = [], nodes = this

      //先取得所有祖先元素
      while (nodes.length > 0)   //到不再有父元素时,退出循环
          //取得所有父元素 //nodes被再赋值为收集到的父元素数组
        nodes = $.map(nodes, function(node){
          //获取父级, isDocument(node) 到Document为止
          //    ancestors.indexOf(node)去重复
          if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
            ancestors.push(node)
            //收集已经获取到的父级元素,用于去重复
            return node
          }
        })

      //筛选出符合selector的祖先元素
      return filtered(ancestors, selector)
    },

这里的$.map还有过滤功能,callback若返回null或undefined,则映射值不会写入nodes数组中。这里的parents的调用者只能是单个dom的zepto集合,先是遍历将所有parentNode获取,然后根据selector调用filtered,选出满足条件的父节点。

 

children:

/**
   * 获取元素的子节集
   * 原理:原生方法children  老的火狐不支持的,遍历childNodes
   * @param element
   * @returns {*}
   */
  function children(element) {
    return 'children' in element ?
        slice.call(element.children) :
        $.map(element.childNodes, function(node){ if (node.nodeType == 1) return node })
  }

/**
     *   获取子元素集
     * @param selector
     * @returns {*|HTMLElement}
     */
    children: function(selector){
      return filtered(this.map(function(){ return children(this) }), selector)
    },

这里主要使用到了element.childNodes获取子节点,并用node.nodeType来剔除不等于1的

siblings:

/**
     * 获取兄弟节点集
     * @param selector
     * @returns {*|HTMLElement}
     */
    siblings: function(selector){
      return filtered(this.map(function(i, el){
        //到其父元素取得所有子节点,再排除本身
        return filter.call(children(el.parentNode), function(child){ return child!==el })
      }), selector)
    },

pre ,next:

  /**
     * 筛选前面所有的兄弟元素
     * @param selector
     * @returns {*}
     */
    prev: function(selector){ return $(this.pluck('previousElementSibling')).filter(selector || '*') },


    /**
     * 筛选后面所有的兄弟元素
     * @param selector
     * @returns {*}
     */
    next: function(selector){ return $(this.pluck('nextElementSibling')).filter(selector || '*') },

 

posted @ 2016-07-07 09:48  潇洒-zhutao  阅读(335)  评论(0编辑  收藏  举报