zepto源碼研究 - zepto.js-3 (經常使用的工具)

pluck:node

/**
     * 根據是否存在此屬性來獲取當前集合,返回一組屬性值
     * @param property
     * @returns {*}
     */
    pluck: function(property){
      return $.map(this, function(el){ return el[property] })
    },

獲取zepto對象的父節點時用到數組

filtered:dom

/**
     *  過濾,返回處理結果爲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:this

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

 

$.map:spa

/**
   * 內部方法
   * 遍歷對象/數組 在每一個元素上執行回調,將回調的返回值放入一個新的數組返回
   * @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:code

/**
     * 取得全部匹配的祖先元素
     * @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:blog

/**
   * 獲取元素的子節集
   * 原理:原生方法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的element

siblings:zepto

/**
     * 獲取兄弟節點集
     * @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 || '*') },
相關文章
相關標籤/搜索