zepto中的屬性設置


上次看zepto的init方法時,有一段屬性設置的代碼,先來看看其表現:

if (isPlainObject(properties)) {
      nodes = $(dom)
      $.each(properties, function(key, value) {
        if (methodAttributes.indexOf(key) > -1) nodes[key](value)
        else nodes.attr(key, value)
      })
    }

在分析這里的時候,一直很困惑,為什么實例化dom之后,對nodes進行屬性設置會導致dom也有了屬性設置的結果。回想了一下,在javascript中,對象是引用,而不是賦值,而dom不是zepto對象就是Dom對象,假如是zepto對象的話,那么nodes其實就是dom,因為在zepto的init方法中,傳入參數是zepto對象的話則直接返回該對象。而如果是其他對象的話,則將其設置為數組的第一個元素返回該數組。

zepto.init = function(selector, context) {
    var dom
      ...
    else if (typeof selector == 'string') {
      ...
    }
     ...
    else if (zepto.isZ(selector)) return selector
    else {
     ...
      else if (isObject(selector))
        dom = [selector], selector = null
      ....
    }
    // create a new Zepto collection from the nodes found
    return zepto.Z(dom, selector)
  }

那么dom = [selector],是不是相當於dom[0] = selector;也是一個引用呢?

實驗結果也就是一個引用。

那么言歸正傳,我們接下來看$.each函數

$.each = function(elements, callback){
    var i, key
    if (likeArray(elements)) {
      for (i = 0; i < elements.length; i++)
        if (callback.call(elements[i], i, elements[i]) === false) return elements
    } else {
      for (key in elements)
        if (callback.call(elements[key], key, elements[key]) === false) return elements
    }

    return elements
  }

該函數事實上並沒有什么特別,對於傳入的第一個參數為要迭代的數組或對象,第二個為回調函數,如果迭代過程中有一個元素或屬性返回false,則返回傳入的第一個參數,否則迭代完再返回第一個參數。

然后就是attr方法了。

attr: function(name, value){
      var result
      return (typeof name == 'string' && !(1 in arguments)) ?
        (0 in this && this[0].nodeType == 1 && (result = this[0].getAttribute(name)) != null ? result : undefined) :
        this.each(function(idx){
          if (this.nodeType !== 1) return
          if (isObject(name)) for (key in name) setAttribute(this, key, name[key])
          else setAttribute(this, name, funcArg(this, value, idx, this.getAttribute(name)))
        })
    },

 

該方法首先判斷傳入的第一個參數是否為一個字符串,並判斷是否有第二個參數,然后根據條件返回讀取屬性的值。

如果傳入的是其他情況,則調用each方法,注意,這里的each是$.fn.each,與上面的$.each不同。

 

 each: function(callback){
      emptyArray.every.call(this, function(el, idx){
        return callback.call(el, idx, el) !== false
      })
      return this
    },

 

each方法傳入一個回調函數,並調用數組的every方法對this(則zepto對象)進行迭代,並將對象的屬性作為回調函數的上下文進行調用。

那么attr方法中,傳入的回調函數,則是首先判斷this的nodeType是否為1,nodeType可以參考這里nodeType。若是,則調用setAttribute方法直接將傳入的key-value對象設置為屬性,否則就通過一個funcArg函數來設置其屬性name的值。

function funcArg(context, arg, idx, payload) {
    return isFunction(arg) ? arg.call(context, idx, payload) : arg
  }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM