设为首页 加入收藏

TOP

读 Zepto 源码之集合元素查找(一)
2017-10-13 10:50:25 】 浏览:1788
Tags:Zepto 源码 集合 元素 查找

这篇依然是跟 dom 相关的方法,侧重点是跟集合元素查找相关的方法。

读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto

源码版本

本文阅读的源码为 zepto1.2.0

内部方法

之前有一章《读Zepto源码之内部方法》是专门解读 zepto 中没有提供给外部使用的内部方法的,但是有几个涉及到 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 方法用于检测元素( element )是否匹配特定的选择器( selector )。

浏览器也有原生的 matches 方法,但是要到IE9之后才支持。具体见文档:Element.matches()

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

这段是确保 selectorelement 两个参数都有传递,并且 element 参数的 nodeTypeELEMENT_NODE ,如何条件不符合,返回 false

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

这段是检测浏览器是否原生支持 matches 方法,或者支持带私有前缀的 matches 方法,如果支持,调用原生的 matches ,并将结果返回。

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

如果原生的方法不支持,则回退到用选择器的方法来检测。

这里定义了三个变量,其中 parent 用来存放 element 的父节点, temp 用来判断 element 是否有父元素。值为 temp = !parent ,如果 element 存在父元素,则 temp 的值为 false

首先判断是否存在父元素,如果父元素不存在,则 parent = tempParenttempParent 已经由一个全局变量来定义,为 tempParent = document.createElement('div') ,其实就是一个 div 空节点。然后将 element 插入到空节点中。

然后,查找 parent 中所有符合选择器 selector 的元素集合,再找出当前元素 element 在集合中的索引。

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

再对索引进行取反操作,这样索引值为 0 的值就变成了 -1,是 -1 的返回的是 0,这样就确保了跟 matches 的表现一致。

其实我有点不太懂的是,为什么不跟原生一样,返回 boolean 类型的值呢?明明通过 zepto.qsa(parent, selector).indexOf(element) > -1 就可以做到了,接口表现一致不是更好吗?

最后还有一步清理操作:

temp && tempParent.removeChild(element)

将空接点的子元素清理点,避免污染。

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

如果检测到浏览器不支持,则降级用 $.map 方法,获取 elementchildNodesnodeTypeELEMENT_NODE 的节点。因为 children 返回的只是元素节点,但是 childNodes 返回的除元素节点外,还包含文本节点、属性等。

这里用到的 $.map 跟数组的原生方法 map 表现有区别,关于 $.map 的具体实现,已经在《读zepto源码之工具函数》解读过了。

filtered

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

将匹配指定选择器的元素从集合中过滤出来。

如果没有指定 selector ,则将集合包裹成 zepto 对象全部返回,否则调用 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 是查找符合条件的元素集合。

参数 selector 可以为 Function 或者选择器,

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇html开发基础 下一篇Javascript继承机制的实现

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目