讀 Zepto 源碼之集合元素查找

這篇依然是跟 dom 相關(guān)的方法,側(cè)重點(diǎn)是跟集合元素查找相關(guān)的方法箕母。

讀Zepto源碼系列文章已經(jīng)放到了github上耍共,歡迎star: reading-zepto

源碼版本

本文閱讀的源碼為 zepto1.2.0

內(nèi)部方法

之前有一章《讀Zepto源碼之內(nèi)部方法》是專門解讀 zepto 中沒有提供給外部使用的內(nèi)部方法的,但是有幾個(gè)涉及到 dom 的方法沒有解讀粟耻,這里先將本章用到的方法解讀一下垢乙。

matches

zepto.matches = function(element, selector) {
  if (!selector || !element || element.nodeType !== 1) return false
  var matchesSelector = element.matches || element.webkitMatchesSelector ||
      element.mozMatchesSelector || element.oMatchesSelector ||
      element.matchesSelector
  if (matchesSelector) return matchesSelector.call(element, selector)
  // fall back to performing a selector:
  var match, parent = element.parentNode,
      temp = !parent
  if (temp)(parent = tempParent).appendChild(element)
    match = ~zepto.qsa(parent, selector).indexOf(element)
    temp && tempParent.removeChild(element)
    return match
}

matches 方法用于檢測(cè)元素( element )是否匹配特定的選擇器( selector )锨咙。

瀏覽器也有原生的 matches 方法,但是要到IE9之后才支持追逮。具體見文檔:Element.matches()

if (!selector || !element || element.nodeType !== 1) return false

這段是確保 selectorelement 兩個(gè)參數(shù)都有傳遞酪刀,并且 element 參數(shù)的 nodeTypeELEMENT_NODE ,如何條件不符合钮孵,返回 false

 var matchesSelector = element.matches || element.webkitMatchesSelector ||
     element.mozMatchesSelector || element.oMatchesSelector ||
     element.matchesSelector
 if (matchesSelector) return matchesSelector.call(element, selector)

這段是檢測(cè)瀏覽器是否原生支持 matches 方法骂倘,或者支持帶私有前綴的 matches 方法,如果支持油猫,調(diào)用原生的 matches 稠茂,并將結(jié)果返回。

var match, parent = element.parentNode,
    temp = !parent
if (temp)(parent = tempParent).appendChild(element)
  match = ~zepto.qsa(parent, selector).indexOf(element)
  temp && tempParent.removeChild(element)
  return match

如果原生的方法不支持,則回退到用選擇器的方法來檢測(cè)睬关。

這里定義了三個(gè)變量诱担,其中 parent 用來存放 element 的父節(jié)點(diǎn), temp 用來判斷 element 是否有父元素电爹。值為 temp = !parent 蔫仙,如果 element 存在父元素,則 temp 的值為 false 丐箩。

首先判斷是否存在父元素摇邦,如果父元素不存在,則 parent = tempParent 屎勘,tempParent 已經(jīng)由一個(gè)全局變量來定義施籍,為 tempParent = document.createElement('div') ,其實(shí)就是一個(gè) div 空節(jié)點(diǎn)概漱。然后將 element 插入到空節(jié)點(diǎn)中丑慎。

然后,查找 parent 中所有符合選擇器 selector 的元素集合瓤摧,再找出當(dāng)前元素 element 在集合中的索引竿裂。

zepto.qsa(parent, selector).indexOf(element)

再對(duì)索引進(jìn)行取反操作奏夫,這樣索引值為 0 的值就變成了 -1调卑,是 -1 的返回的是 0各聘,這樣就確保了跟 matches 的表現(xiàn)一致脏毯。

其實(shí)我有點(diǎn)不太懂的是,為什么不跟原生一樣攻柠,返回 boolean 類型的值呢循帐?明明通過 zepto.qsa(parent, selector).indexOf(element) > -1 就可以做到了瞬浓,接口表現(xiàn)一致不是更好嗎给赞?

最后還有一步清理操作:

temp && tempParent.removeChild(element)

將空接點(diǎn)的子元素清理點(diǎn)这嚣,避免污染。

children

function children(element) {
  return 'children' in element ?
    slice.call(element.children) :
  $.map(element.childNodes, function(node) { if (node.nodeType == 1) return node })
}

children 方法返回的是 element 的子元素集合塞俱。

瀏覽器也有原生支持元素 children 屬性,也要到IE9以上才支持吏垮,見文檔ParentNode.children

如果檢測(cè)到瀏覽器不支持障涯,則降級(jí)用 $.map 方法,獲取 elementchildNodesnodeTypeELEMENT_NODE 的節(jié)點(diǎn)膳汪。因?yàn)?children 返回的只是元素節(jié)點(diǎn)唯蝶,但是 childNodes 返回的除元素節(jié)點(diǎn)外,還包含文本節(jié)點(diǎn)遗嗽、屬性等粘我。

這里用到的 $.map 跟數(shù)組的原生方法 map 表現(xiàn)有區(qū)別,關(guān)于 $.map 的具體實(shí)現(xiàn),已經(jīng)在《讀zepto源碼之工具函數(shù)》解讀過了征字。

filtered

function filtered(nodes, selector) {
  return selector == null ? $(nodes) : $(nodes).filter(selector)
}

將匹配指定選擇器的元素從集合中過濾出來都弹。

如果沒有指定 selector ,則將集合包裹成 zepto 對(duì)象全部返回匙姜,否則調(diào)用 filter 方法畅厢,過濾出符合條件的元素返回。filter 方法下面馬上講到氮昧。

元素方法

這里的方法都是 $.fn 中提供的方法框杜。

.filter()

filter: function(selector) {
  if (isFunction(selector)) return this.not(this.not(selector))
  return $(filter.call(this, function(element) {
    return zepto.matches(element, selector)
  }))
}

filter 是查找符合條件的元素集合。

參數(shù) selector 可以為 Function 或者選擇器袖肥,當(dāng)為 Function 時(shí)咪辱,調(diào)用的其實(shí)調(diào)用了兩次 not 方法,負(fù)負(fù)得正椎组。關(guān)于 not 方法油狂,下面馬上會(huì)看到。

當(dāng)為一般的選擇器時(shí)庐杨,調(diào)用的是filter 方法选调,filter 的回調(diào)函數(shù)調(diào)用了 matches ,將符合 selector 的元素返回灵份,并包裝成 zepto 對(duì)象返回仁堪。

.not()

not: function(selector) {
  var nodes = []
  if (isFunction(selector) && selector.call !== undefined)
    this.each(function(idx) {
      if (!selector.call(this, idx)) nodes.push(this)
        })
    else {
      var excludes = typeof selector == 'string' ? this.filter(selector) :
      (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
      this.forEach(function(el) {
        if (excludes.indexOf(el) < 0) nodes.push(el)
          })
    }
  return $(nodes)
}

not 方法是將集合中不符合條件的元素查找出來。

not 方法的方法有三種調(diào)用方式:

not(selector)  ? collection
not(collection)  ? collection
not(function(index){ ... })  ? collection

當(dāng) selectorFunction 填渠,并且有 call 方法時(shí)(isFunction(selector) && selector.call !== undefined)弦聂,相關(guān)的代碼如下:

this.each(function(idx) {
  if (!selector.call(this, idx)) nodes.push(this)
    })

調(diào)用 each 方法,并且在 selector 函數(shù)中氛什,可以訪問到當(dāng)前的元素和元素的索引莺葫。如果 selector 函數(shù)的值取反后為 true,則將相應(yīng)的元素放入 nodes 數(shù)組中枪眉。

當(dāng) selector 不為 Function 時(shí)捺檬, 定義了一個(gè)變量 excludes ,這個(gè)變量來用接收需要排除的元素集合贸铜。接下來又是一串三元表達(dá)式(zepto的特色氨の场)

typeof selector == 'string' ? this.filter(selector)

當(dāng) selectorstring 時(shí),調(diào)用 filter 蒿秦,找出所有需要排除的元素

(likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)

這段我剛開始看時(shí)烤镐,有點(diǎn)困惑,主要是不明白 isFunction(selector.item) 這個(gè)判斷條件棍鳖,后來查了MDN文檔HTMLCollection.item炮叶,才明白 itemHTMLCollection 的一個(gè)方法,這個(gè)三元表達(dá)式的意思是,如果是 HTMLCollection 镜悉,則調(diào)用 slice.call 得到一個(gè)純數(shù)組祟辟,否則返回 zepto 對(duì)象。

this.forEach(function(el) {
    if (excludes.indexOf(el) < 0) nodes.push(el)
})

遍歷集合积瞒,如果元素不在需要排除的元素集合中川尖,將該元素 push 進(jìn) nodes 中。

not 方法最終返回的也是 zepto 對(duì)象茫孔。

.is()

is: function(selector) {
  return this.length > 0 && zepto.matches(this[0], selector)
}

判斷集合中的第一個(gè)元素是否匹配指定的選擇器叮喳。

代碼也比較簡(jiǎn)單了,選判斷集合不為空缰贝,再調(diào)用 matches 看第一個(gè)元素是否匹配馍悟。

.find()

find: function(selector) {
  var result, $this = this
  if (!selector) result = $()
  else if (typeof selector == 'object')
    result = $(selector).filter(function() {
      var node = this
      return emptyArray.some.call($this, function(parent) {
        return $.contains(parent, node)
      })
    })
    else if (this.length == 1) result = $(zepto.qsa(this[0], selector))
    else result = this.map(function() { return zepto.qsa(this, selector) })
    return result
}

find 是查找集合中符合選擇器的所有后代元素,如果給定的是 zepto 對(duì)象或者 dom 元素剩晴,則只有他們?cè)诋?dāng)前的集合中時(shí)锣咒,才返回。

fid 有三種調(diào)用方式赞弥,如下:

find(selector)   ? collection
find(collection)   ? collection
find(element)   ? collection
if (!selector) result = $()

如果不傳參時(shí)毅整,返回的是空的 zepto 對(duì)象。

else if (typeof selector == 'object')
  result = $(selector).filter(function() {
    var node = this
    return emptyArray.some.call($this, function(parent) {
      return $.contains(parent, node)
    })
  })

如果傳參為 object 時(shí)绽左,也就是 zepto 對(duì)象collectiondom 節(jié)點(diǎn) element 時(shí)悼嫉,先將 selector 包裹成 zepto 對(duì)象,然后對(duì)這個(gè)對(duì)象過濾拼窥,返回當(dāng)前集合子節(jié)點(diǎn)中所包含的元素($.contains(parent, node))戏蔑。

else if (this.length == 1) result = $(zepto.qsa(this[0], selector))

如果當(dāng)前的集合只有一個(gè)元素時(shí),直接調(diào)用 zepto.qsa 方法鲁纠,取出集合的第一個(gè)元素 this[0] 作為 qsa 的第一個(gè)參數(shù)总棵。關(guān)于 qsa 方法,已經(jīng)在《讀Zepto源碼之神奇的$》分析過了改含。其實(shí)就是獲取第一個(gè)元素的所有后代元素情龄。

else result = this.map(function() { return zepto.qsa(this, selector) })

否則,調(diào)用 map 方法捍壤,對(duì)集合中每個(gè)元素都調(diào)用 qsa 方法刃唤,獲取所有元素的后代元素。這個(gè)條件其實(shí)可以與上一個(gè)條件合并的白群,分開應(yīng)該是為了性能的考量。

.has()

has: function(selector) {
  return this.filter(function() {
    return isObject(selector) ?
      $.contains(this, selector) :
    $(this).find(selector).size()
  })
},

判斷集合中是否有包含指定條件的子元素硬霍,將符合條件的元素返回帜慢。

有兩種調(diào)用方式

has(selector)   ? collection
has(node)   ? collection

參數(shù)可以為選擇器或者節(jié)點(diǎn)。

has 其實(shí)調(diào)用的是 filter 方法,這個(gè)方法上面已經(jīng)解讀過了粱玲。filter 的回調(diào)函數(shù)中根據(jù)參數(shù)的不同情況躬柬,調(diào)用了不同的方法。

isObject(selector) 用來判斷 selector 是否為 node 節(jié)點(diǎn)抽减,如果為 node 節(jié)點(diǎn)允青,則調(diào)用 $.contains 方法,該方法已經(jīng)在《讀Zepto源碼之工具函數(shù)》說過了卵沉。

如果為選擇器颠锉,則調(diào)用 find 方法,然后再調(diào)用 size 方法史汗,size 方法返回的是集合中元素的個(gè)數(shù)琼掠。這個(gè)在《讀Zepto源碼之集合操作》有講過,如果集合個(gè)數(shù)大于零停撞,則表示滿足條件瓷蛙。

.eq()

eq: function(idx) {
  return idx === -1 ? this.slice(idx) : this.slice(idx, +idx + 1)
},

獲取集合中指定的元素。

這里調(diào)用了 slice 方法戈毒,這個(gè)方法在上一篇《讀Zepto源碼之集合操作》已經(jīng)說過了艰猬。如果 idx-1 時(shí),直接調(diào)用 this.slice(idx) 埋市,即取出最后一個(gè)元素冠桃,否則取 idxidx + 1 之間的元素,也就是每次只取一個(gè)元素恐疲。+idx+1 前面的 + 號(hào)其實(shí)是類型轉(zhuǎn)換腊满,確保 idx 在做加法的時(shí)候?yàn)?Number 類型。

.first()

first: function() {
  var el = this[0]
  return el && !isObject(el) ? el : $(el)
},

first 是取集合中第一個(gè)元素培己,這個(gè)方法很簡(jiǎn)單碳蛋,用索引 0 就可以取出來了,也就是 this[0] 省咨。

el && !isObject(el) 用來判斷是否為 zepto 對(duì)象肃弟,如果不是,用 $(el) 包裹零蓉,確保返回的是 zepto 對(duì)象笤受。

.last()

last: function() {
  var el = this[this.length - 1]
  return el && !isObject(el) ? el : $(el)
},

last 是取集合中最后一個(gè)元素,這個(gè)的原理跟 first 一樣敌蜂,只不過變成了取索引值為 this.length - 1 箩兽,也就是最后的元素。

.closest()

closest: function(selector, context) {
  var nodes = [],
      collection = typeof selector == 'object' && $(selector)
  this.each(function(_, node) {
    while (node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector)))
      node = node !== context && !isDocument(node) && node.parentNode
      if (node && nodes.indexOf(node) < 0) nodes.push(node)
        })
  return $(nodes)
},

從元素本身向上查找章喉,返回最先符合條件的元素汗贫。

這個(gè)方法也有三種調(diào)用方式

closest(selector, [context])   ? collection
closest(collection)   ? collection 
closest(element)   ? collection 

如果指定了 zepto 集合或者 element 身坐,則只返回匹配給定集合或 element 的元素。

collection = typeof selector == 'object' && $(selector)

這段是判斷 selector 是否為 collectionelement 落包,如果是部蛇,則統(tǒng)一轉(zhuǎn)化為 zepto 集合。

然后對(duì)集合遍歷咐蝇,在 each 遍歷里針對(duì)集合中每個(gè) node 節(jié)點(diǎn)涯鲁,都用 while 語句,向上查找符合條件的元素有序。

node && !(collection ? collection.indexOf(node) >= 0 : zepto.matches(node, selector))

這段是 while 語句的終止條件抹腿。 node 節(jié)點(diǎn)必須存在,如果 selectorzepto 集合或者 element 笔呀,也即 collection 存在幢踏, 則要找到存在于 collection 中的節(jié)點(diǎn)(collection.indexOf(node) >= 0), 否則许师,節(jié)點(diǎn)要匹配指定的選擇器(zepto.matches(node, selector)

while 循環(huán)中房蝉,是向上逐級(jí)查找節(jié)點(diǎn)的過程:

node = node !== context && !isDocument(node) && node.parentNode

當(dāng)前 node 不為指定的上下文 context 并且不為 document 節(jié)點(diǎn)時(shí),向上查找(node.parentNode

if (node && nodes.indexOf(node) < 0) nodes.push(node)

while 循環(huán)完畢后微渠,如果 node 節(jié)點(diǎn)存在搭幻,并且 nodes 中還不存在 node ,則將 node push 進(jìn) nodes 中逞盆。

最后返回 zepto 集合檀蹋。

.pluck()

pluck: function(property) {
  return $.map(this, function(el) { return el[property] })
},

返回集合中所有元素指定的屬性值。

這個(gè)方法很簡(jiǎn)單云芦,就是對(duì)當(dāng)前集合遍歷俯逾,然后取元素指定的 property 值。

.parents()

parents: function(selector) {
  var ancestors = [],
      nodes = this
  while (nodes.length > 0)
    nodes = $.map(nodes, function(node) {
      if ((node = node.parentNode) && !isDocument(node) && ancestors.indexOf(node) < 0) {
        ancestors.push(node)
        return node
      }
    })
    return filtered(ancestors, selector)
},

返回集合中所有元素的所有祖先元素舅逸。

nodes 的初始值為當(dāng)前集合桌肴,while 循環(huán)的條件為集合不為空。

使用 map 遍歷 nodes 琉历,將 node 重新賦值為自身的父級(jí)元素坠七,如果父級(jí)元素存在,并且不是 document 元素旗笔,而且還不存在于 ancestors 中時(shí)彪置,將 node 存入保存祖先元素的 ancestors 中,并且 map 回調(diào)的返回值是 node 蝇恶,組成新的集合賦值給 nodes 拳魁,直到所有的祖先元素遍歷完畢,就可以退出 while 循環(huán)撮弧。

最后潘懊,調(diào)用上面說到的 filtered 方法耀盗,找到符合 selector 的祖先元素。

.parent()

parent: function(selector) {
  return filtered(uniq(this.pluck('parentNode')), selector)
},

返回集合中所有元素的父級(jí)元素卦尊。

parents 返回的是所有祖先元素,而 parent 返回只是父級(jí)元素舌厨。

首先調(diào)用的是 this.pluck('parentNode') 岂却,獲取所有元素的祖先元素,然后調(diào)用 uniq 對(duì)集合去重裙椭,最后調(diào)用 filtered 躏哩,返回匹配 selector 的元素集合。

.children()

children: function(selector) {
  return filtered(this.map(function() { return children(this) }), selector)
},

返回集合中所有元素的子元素揉燃。

首先對(duì)當(dāng)前集合遍歷扫尺,調(diào)用內(nèi)部方法 children 獲取當(dāng)前元素的子元素組成新的數(shù)組,再調(diào)用 filtered 方法返回匹配 selector 的元素集合炊汤。

.contents()

contents: function() {
  return this.map(function() { return this.contentDocument || slice.call(this.childNodes) })
},

這個(gè)方法類似于 children 正驻,不過 children 對(duì) childNodes 進(jìn)行了過濾,只返回元素節(jié)點(diǎn)抢腐。contents 還返回文本節(jié)點(diǎn)和注釋節(jié)點(diǎn)姑曙。也返回 iframecontentDocument

.siblings()

siblings: function(selector) {
  return filtered(this.map(function(i, el) {
    return filter.call(children(el.parentNode), function(child) { return child !== el })
  }), selector)
},

獲取所有集合中所有元素的兄弟節(jié)點(diǎn)。

獲取兄弟節(jié)點(diǎn)的思路也很簡(jiǎn)單迈倍,對(duì)當(dāng)前集合遍歷伤靠,找到當(dāng)前元素的父元素el.parentNode,調(diào)用 children 方法啼染,找出父元素的子元素宴合,將子元素中與當(dāng)前元素不相等的元素過濾出來即是其兄弟元素了。

最后調(diào)用 filtered 來過濾出匹配 selector 的兄弟元素迹鹅。

.prev()

prev: function(selector) { return $(this.pluck('previousElementSibling')).filter(selector || '*') },

獲取集合中每個(gè)元素的前一個(gè)兄弟節(jié)點(diǎn)卦洽。

這個(gè)方法也很簡(jiǎn)單,調(diào)用 pluck 方法徒欣,獲取元素的 previousElementSibling 屬性逐样,即為元素的前一個(gè)兄弟節(jié)點(diǎn)。再調(diào)用 filter 返回匹配 selector 的元素打肝,最后包裹成 zepto 對(duì)象返回

.next()

next: function(selector) { return $(this.pluck('nextElementSibling')).filter(selector || '*') },

next 方法跟 prev 方法類似脂新,只不過取的是 nextElementSibling 屬性,獲取的是每個(gè)元素的下一個(gè)兄弟節(jié)點(diǎn)粗梭。

.index()

index: function(element) {
  return element ? this.indexOf($(element)[0]) : this.parent().children().indexOf(this[0])
},

返回指定元素在當(dāng)前集合中的位置(this.indexOf($(element)[0]))争便,如果沒有給出 element ,則返回當(dāng)前鮮紅在兄弟元素中的位置断医。this.parent().children() 查找的是兄弟元素滞乙。

系列文章

  1. 讀Zepto源碼之代碼結(jié)構(gòu)
  2. 讀 Zepto 源碼之內(nèi)部方法
  3. 讀Zepto源碼之工具函數(shù)
  4. 讀Zepto源碼之神奇的$
  5. 讀Zepto源碼之集合操作

參考

License

最后奏纪,所有文章都會(huì)同步發(fā)送到微信公眾號(hào)上,歡迎關(guān)注,歡迎提意見:

作者:對(duì)角另一面

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斩启,一起剝皮案震驚了整個(gè)濱河市序调,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌兔簇,老刑警劉巖发绢,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異垄琐,居然都是意外死亡边酒,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門狸窘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來墩朦,“玉大人,你說我怎么就攤上這事翻擒∶セ粒” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵韭寸,是天一觀的道長(zhǎng)春哨。 經(jīng)常有香客問我,道長(zhǎng)恩伺,這世上最難降的妖魔是什么赴背? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮晶渠,結(jié)果婚禮上凰荚,老公的妹妹穿的比我還像新娘。我一直安慰自己褒脯,他們只是感情好便瑟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著番川,像睡著了一般到涂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颁督,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天践啄,我揣著相機(jī)與錄音,去河邊找鬼沉御。 笑死屿讽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的吠裆。 我是一名探鬼主播伐谈,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼烂完,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了诵棵?” 一聲冷哼從身側(cè)響起抠蚣,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎履澳,沒想到半個(gè)月后柱徙,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奇昙,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敌完。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片储耐。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖滨溉,靈堂內(nèi)的尸體忽然破棺而出什湘,到底是詐尸還是另有隱情,我是刑警寧澤晦攒,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布闽撤,位于F島的核電站,受9級(jí)特大地震影響脯颜,放射性物質(zhì)發(fā)生泄漏哟旗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一栋操、第九天 我趴在偏房一處隱蔽的房頂上張望闸餐。 院中可真熱鬧,春花似錦矾芙、人聲如沸舍沙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)拂铡。三九已至,卻和暖如春葱绒,著一層夾襖步出監(jiān)牢的瞬間感帅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工哈街, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留留瞳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓骚秦,卻偏偏與公主長(zhǎng)得像她倘,于是被迫代替她去往敵國(guó)和親璧微。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 經(jīng)過前面三章的鋪墊硬梁,這篇終于寫到了戲肉前硫。在用 zepto 時(shí),肯定離不開這個(gè)神奇的 $ 符號(hào)荧止,這篇文章將會(huì)看看 z...
    對(duì)角另一面閱讀 584評(píng)論 1 3
  • Zepto 的 Data 模塊用來獲取 DOM 節(jié)點(diǎn)中的 data-* 屬性的數(shù)據(jù)屹电,和儲(chǔ)存跟 DOM 相關(guān)的數(shù)據(jù)。...
    對(duì)角另一面閱讀 576評(píng)論 0 1
  • 下了好多天雨 ...
    不如名字閱讀 249評(píng)論 0 1
  • 前幾日跃巡,專業(yè)課上危号,老師拋出這樣一個(gè)題目,要求大家以“我最感謝的人”為主題說一個(gè)五分鐘的演講素邪。我當(dāng)時(shí)雖然覺得這個(gè)題目...
    芊唯Sharon閱讀 161評(píng)論 0 0
  • 春天來了兔朦,不管冬天如何的殘酷偷线,終將過去,而我所要做的在春暖花開時(shí)節(jié)沽甥,學(xué)會(huì)養(yǎng)生保健声邦。 買一個(gè)好壺,來幾朵玫瑰花摆舟,簡(jiǎn)單...
    如緣夏雨閱讀 212評(píng)論 0 0