国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

讀Zepto源碼之Selector模塊

Jioby / 2986人閱讀

摘要:如果偽類的參數不可以用轉換,則參數為字符串,用正則將字符串前后的或去掉,再賦值給最后執行回調,將解釋出來的參數傳入回調函數中,將執行結果返回。重寫的方法,改過的調用的是方法,在回調函數中處理大部分邏輯。

Selector 模塊是對 Zepto 選擇器的擴展,使得 Zepto 選擇器也可以支持部分 CSS3 選擇器和 eqZepto 定義的選擇器。

在閱讀本篇文章之前,最好先閱讀《讀Zepto源碼之神奇的$》。

讀 Zepto 源碼系列文章已經放到了github上,歡迎star: reading-zepto

源碼版本

本文閱讀的源碼為 zepto1.2.0

GitBook

《reading-zepto》

輔助方法 visible
function visible(elem){
  elem = $(elem)
  return !!(elem.width() || elem.height()) && elem.css("display") !== "none"
}

判斷元素是否可見。

可見的標準是元素有寬或者高,并且 display 值不為 none

filters
var filters = $.expr[":"] = {
  visible:  function(){ if (visible(this)) return this },
  hidden:   function(){ if (!visible(this)) return this },
  selected: function(){ if (this.selected) return this },
  checked:  function(){ if (this.checked) return this },
  parent:   function(){ return this.parentNode },
  first:    function(idx){ if (idx === 0) return this },
  last:     function(idx, nodes){ if (idx === nodes.length - 1) return this },
  eq:       function(idx, _, value){ if (idx === value) return this },
  contains: function(idx, _, text){ if ($(this).text().indexOf(text) > -1) return this },
  has:      function(idx, _, sel){ if (zepto.qsa(this, sel).length) return this }
}

定義了一系列的過濾函數,返回符合條件的元素。這些過濾函數會將集合中符合條件的元素過濾出來,是實現相關選擇器的核心。

visible: 過濾可見元素,匹配 el:visible 選擇器

hidden: 過濾不可見元素, 匹配 el:hidden 選擇器

selected: 過濾選中的元素,匹配 el:selected 選擇器

checked: 過濾勾選中的元素,匹配 el:checked 選擇器

parent: 返回至少包含一個子元素的元素,匹配 el:parent 選擇器

first: 返回第一個元素,匹配 el:first 選擇器

last: 返回最后一個元素,匹配 el:last 選擇器

eq: 返回指定索引的元素,匹配 el:eq(index) 選擇器

contains: 返回包含指定文本的元素,匹配 el:contains(text)

has: 返回匹配指定選擇器的元素,匹配 el:has(sel)

process
var filterRe = new RegExp("(.*):(w+)(?:(([^)]+)))?$s*"),
function process(sel, fn) {
  sel = sel.replace(/=#]/g, "="#"]")
  var filter, arg, match = filterRe.exec(sel)
  if (match && match[2] in filters) {
    filter = filters[match[2]], arg = match[3]
    sel = match[1]
    if (arg) {
      var num = Number(arg)
      if (isNaN(num)) arg = arg.replace(/^[""]|[""]$/g, "")
      else arg = num
    }
  }
  return fn(sel, filter, arg)
}

process 方法是根據參數 sel,分解出選擇器、偽類名和偽類參數(如 eqhas 的參數),根據偽類來選擇對應的 filter ,傳遞給回調函數 fn

分解參數最主要靠的是 filterRe 這條正則,正則太過復雜,很難解釋,不過用正則可視化網站 regexper.com,可以很清晰地看到,正則分成三大組,第一組匹配的是 : 前面的選擇器,第二組匹配的是偽類名,第三組匹配的是偽類參數。

sel = sel.replace(/=#]/g, "="#"]")

這段是處理 a[href^=#] 的情況,其實就是將 # 包在 "" 里面,以符合標準的屬性選擇器,這是 Zepto 的容錯能力。 這個選擇器不會匹配到 filters 上的過濾函數,最后調用的是 querySelectorAll 方法,具體見《讀Zepto源碼之神奇的$》對 qsa 函數的分析。

if (match && match[2] in filters) {
  filter = filters[match[2]], arg = match[3]
  sel = match[1]
  ...
}

match[2] 也即第二組匹配的是偽類名,也是對應 filters 中的 key 值,偽類名存在于 filters 中時,則將選擇器,偽類名和偽類參數存入對應的變量。

if (arg) {
  var num = Number(arg)
  if (isNaN(num)) arg = arg.replace(/^[""]|[""]$/g, "")
  else arg = num
}

如果偽類的參數不可以用 Number 轉換,則參數為字符串,用正則將字符串前后的 "" 去掉,再賦值給 arg.

return fn(sel, filter, arg)

最后執行回調,將解釋出來的參數傳入回調函數中,將執行結果返回。

重寫的方法 qsa
var zepto = $.zepto, oldQsa = zepto.qsa, oldMatches = zepto.matches,
    childRe  = /^s*>/,
    classTag = "Zepto" + (+new Date())

zepto.qsa = function(node, selector) {
  return process(selector, function(sel, filter, arg){
    try {
      var taggedParent
      if (!sel && filter) sel = "*"
      else if (childRe.test(sel))
        taggedParent = $(node).addClass(classTag), sel = "."+classTag+" "+sel

      var nodes = oldQsa(node, sel)
      } catch(e) {
        console.error("error performing selector: %o", selector)
        throw e
      } finally {
        if (taggedParent) taggedParent.removeClass(classTag)
      }
    return !filter ? nodes :
    zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))
  })
}

改過的 qsa 調用的是 process 方法,在回調函數中處理大部分邏輯。

思路是通過選擇器獲取到所有節點,然后再調用對應偽類的對應方法來過濾出符合條件的節點。

處理選擇器,根據選擇器獲取節點
var taggedParent
if (!sel && filter) sel = "*"
else if (childRe.test(sel))
  taggedParent = $(node).addClass(classTag), sel = "."+classTag+" "+sel

var nodes = oldQsa(node, sel)

如果選擇器和過濾器都不存在,則將 sel 設置 * ,即獲取所有元素。

如果 >sel 形式的選擇器,查找所有子元素。

這里的做法是,向元素 node 中添加唯一的樣式名 classTag,然后用唯一樣式名和選擇器拼接成子元素選擇器。

最后調用原有的 qsa 函數 oldQsa 來獲取符合選擇器的所有元素。

清理所添加的樣式
if (taggedParent) taggedParent.removeClass(classTag)

如果存在 taggedParent ,則將元素上的 classTag 清理掉。

調用對應的過濾器,過濾元素
return !filter ? nodes :
    zepto.uniq($.map(nodes, function(n, i){ return filter.call(n, i, nodes, arg) }))

如果沒有過濾器,則將所有元素返回,如果存在過濾器,則遍歷集合,調用對應的過濾器獲取元素,并將新集合的元素去重。

matches
zepto.matches = function(node, selector){
  return process(selector, function(sel, filter, arg){
    return (!sel || oldMatches(node, sel)) &&
      (!filter || filter.call(node, null, arg) === node)
  })
}

matches 也是調用 process 方法,這里很巧妙地用了 ||&& 的短路操作。

其實要做的事情就是,如果可以用 oldMatches 匹配,則使用 oldMatches 匹配的結果,否則使用過濾器過濾出來的結果。

系列文章

讀Zepto源碼之代碼結構

讀Zepto源碼之內部方法

讀Zepto源碼之工具函數

讀Zepto源碼之神奇的$

讀Zepto源碼之集合操作

讀Zepto源碼之集合元素查找

讀Zepto源碼之操作DOM

讀Zepto源碼之樣式操作

讀Zepto源碼之屬性操作

讀Zepto源碼之Event模塊

讀Zepto源碼之IE模塊

讀Zepto源碼之Callbacks模塊

讀Zepto源碼之Deferred模塊

讀Zepto源碼之Ajax模塊

讀Zepto源碼之assets模塊

參考

try-catch語句的“偽塊作用域”

License

署名-非商業性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)

最后,所有文章都會同步發送到微信公眾號上,歡迎關注,歡迎提意見:

作者:對角另一面

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91886.html

相關文章

  • Zepto源碼Event模塊

    摘要:不支持事件冒泡帶來的直接后果是不能進行事件委托,所以需要對和事件進行模擬。調用函數,分隔出參數的事件名和命名空間。這里判斷是否為函數,即第一種傳參方式,調用函數的方法,將上下文對象作為的第一個參數,如果存在,則與的參數合并。 Event 模塊是 Zepto 必備的模塊之一,由于對 Event Api 不太熟,Event 對象也比較復雜,所以乍一看 Event 模塊的源碼,有點懵,細看下...

    vpants 評論0 收藏0
  • Zepto源碼Stack模塊

    摘要:讀源碼系列文章已經放到了上,歡迎源碼版本本文閱讀的源碼為改寫原有的方法模塊改寫了以上這些方法,這些方法在調用的時候,會為返回的結果添加的屬性,用來保存原來的集合。方法的分析可以看讀源碼之模塊。 Stack 模塊為 Zepto 添加了 addSelf 和 end 方法。 讀 Zepto 源碼系列文章已經放到了github上,歡迎star: reading-zepto 源碼版本 本文閱讀的...

    crossea 評論0 收藏0
  • Zepto源碼Gesture模塊

    摘要:模塊基于上的事件的封裝,利用屬性,封裝出系列事件。這個判斷需要引入設備偵測模塊。然后是監測事件,根據這三個事件,可以組合出和事件。其中變量對象和模塊中的對象的作用差不多,可以先看看讀源碼之模塊對模塊的分析。 Gesture 模塊基于 IOS 上的 Gesture 事件的封裝,利用 scale 屬性,封裝出 pinch 系列事件。 讀 Zepto 源碼系列文章已經放到了github上,歡...

    coolpail 評論0 收藏0
  • Zepto源碼Form模塊

    摘要:模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數據,另一部分是觸發事件,提交表單。最終返回的結果是一個數組,每個數組項為包含和屬性的對象。否則手動綁定事件,如果沒有阻止瀏覽器的默認事件,則在第一個表單上觸發,提交表單。 Form 模塊處理的是表單提交。表單提交包含兩部分,一部分是格式化表單數據,另一部分是觸發 submit 事件,提交表單。 讀 Zepto 源碼系列文章已...

    陳江龍 評論0 收藏0
  • Zepto源碼fx_methods模塊

    摘要:所以模塊依賴于模塊,在引入前必須引入模塊。原有的方法分析見讀源碼之樣式操作方法首先調用原有的方法,將元素顯示出來,這是實現動畫的基本條件。如果沒有傳遞,或者為值,則表示不需要動畫,調用原有的方法即可。 fx 模塊提供了 animate 動畫方法,fx_methods 利用 animate 方法,提供一些常用的動畫方法。所以 fx_methods 模塊依賴于 fx 模塊,在引入 fx_m...

    junbaor 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<