Zepto源码之$.fn工具函数

$.fn.get

从当前对象集合中获取所有元素或单个元素。当index参数不存在的时,以普通数组的方式返回所有的元素。当指定index时,只返回该置的元素。这点与eq不同,该方法返回的是DOM节点,不是Zepto对象集合。

get: function(idx){
   
      return idx === undefined ? slice.call(this) : this[idx >= 0 ? idx : idx + this.length]
    },

// 这里用的是三目运算符,我们可以简单的改写一下
get: function(idx) {
   
    if(idx === undefined) {
    // 没有设置 idx 返回全部的元素 
        return slice.call(this)
        // this.slice()
    } else {
    // 设置了 idx 的情况,取对应的元素
        if(idx >= 0) {
            // idx 大于等于0 从头开始取
            return this[idx]
        } else {
             // idx 小于0 从尾开始取
            return this[idx + this.length]
        }
    }
}

$.fn.toArray

这是一个彩蛋惊喜,本质是暴露出来的,不过官方的API文档上并没有。其主要是内部使用,用于调用 $.fn.get 把传入的 zepto 对象转化成一个数组。

toArray: function(){
    return this.get() },

$.fn.concat

添加元素到一个Zepto对象集合形成一个新数组。如果参数是一个数组,那么这个数组中的元素将会合并到Zepto对象集合中。

concat: function(){
   
      var i, value, args = []
      // 遍历传入的参数
      for (i = 0; i < arguments.length; i++) {
        value = arguments[i]
        // 检测元素是不是 zepto 对象,如果是,那么转化成数组插入到 临时数组中,如果是元素,那么直接插入到临时数组中 
        args[i] = zepto.isZ(value) ? value.toArray() : value
      }
      // 检测当前调用 concat函数的对象是不是 zepto 对象,如果是那么先转化成数组再与args拼接,否则直接与args拼接。返回拼接结果
      return concat.apply(zepto.isZ(this) ? this.toArray() : this, args)
    },

map

遍历对象集合中的所有元素。通过遍历函数返回值形成一个新的集合对象。

map: function(fn){
   
      // 先调用 $.map 方法,把对象中的数据全用 fn 处理一遍,生成一个数组。再将数组中的内容通过 $() 方法转化成 zepto 对象。
      return $($.map(this, function(el, i){
    return fn.call(el, i, el) }))
    },

slice

提取这个数组array的子集,从start开始,如果给定end,提取从从start开始到end结束的元素,但是不包含end位置的元素。

slice: function(){
   
      // 调用 slice 方法,截取该数组,并转化成 zepto 对象 
      return $(slice.apply(this, arguments))
    },

ready

ready: function(callback){
   
      // 通过检测 document.readyState 来判断页面是否加载成功,  
      // doScroll 是用于检测 IE 浏览器加载状态的
      // 如果页面加载成功,那么立即将回调函数放在执行队形中
      if (document.readyState === "complete" ||
          (document.readyState !== "loading" && !document.documentElement.doScroll))
        setTimeout(function(){
    callback($) }, 0)
      else {
        // 添加事件监听,如果监听到 DOMContented 或者 load 事件,那么就表明页面执行完成,执行 handler
        var handler = function() {
   
          document.removeEventListener("DOMContentLoaded", handler, false)
          window.removeEventListener("load", handler, false)
          callback($)
        }
        document.addEventListener("DOMContentLoaded", handler, false)
        window.addEventListener("load", handler, false)
      }
      return this
    },

size

获取对象集合中元素的数量。

size: function(){
   
      return this.length
    },

each

遍历一个对象集合每个元素。如果迭代函数返回 false,遍历结束。

// emptyArray 的定义在顶部数据定义部分
emptyArray = []

each: function(callback){
   
      // 使用 Array.prototype.every 然后监测返回值,就可以做到当迭代函数返回 false 时,遍历结束
      emptyArray.every.call(this, function(el, idx){
   
        return callback.call(el, idx, el) !== false
      })
      return this
    },

remove

从其父节点中删除当前集合中的元素,有效的从dom中移除。

remove: function(){
   
      // 本函数本质上是返回 this 。即当前操作的 zepto 对象。这样做的好处是可以链式调用
      return this.each(function(){
   
      // 遍历当前操作的 zepto 对象。如果其存在父元素,那么就将其从父元素中移除
        if (this.parentNode != null)
          this.parentNode.removeChild(this)
      })
    },

not

过滤当前对象集合,获取一个新的对象集合,它里面的元素不能匹配css选择器。如果另一个参数为Zepto对象集合,那么返回的新Zepto对象中的元素都不包含在该参数对象中。如果参数是一个函数。仅仅包含函数执行为false值得时候的元素,函数的 this 关键字指向当前循环元素。

not: function(selector){
   
      var nodes=[]
      // 如果传入内容是一个函数,且函数存在call方法
      if (isFunction(selector) && selector.call !== undefined)
        // 对当前指向的DOM数组执行 each 方法,如果返回值为false,传到到nodes数组中        
        this.each(function(idx){
   
          if (!selector.call(this,idx)) nodes.push(this)
        })
      else {
        // 当 selector 为字符串时,对数组进行筛选,找出满足selector的内容
        // 当 selector 为 nodeList 时执行 slice.call(selector) ,这里的isFunction(selector.item)是为了排除selector为数组的情况
        //当selector为css选择器,执行$(selector)
        var excludes = typeof selector == 'string' ? this.filter(selector) :
          (likeArray(selector) && isFunction(selector.item)) ? slice.call(selector) : $(selector)
        //筛选出不在 excludes 数组中的记录,达到除去的目的
        this.forEach(function(el){
   
          if (excludes.indexOf(el) < 0) nodes.push(el)
        })
      }
      // 将nodes数组转化成 zepto 对象并返回
      return $(nodes)
    },

filter

过滤对象集合,返回对象集合中满足css选择器的项。如果参数为一个函数,函数返回有实际值得时候,元素才会被返回。

filter: function(selector){
   
      // 如果传入内容是个函数,那么返回 两次not函数筛选的结果,负负为正
      if (isFunction(selector)) return this.not(this.not(selector))
      // 如果传入的是一个css选择器,那么执行 matches 来筛选,并将结果转化成一个 zepto 数组
      return $(filter.call(this, function(element){
   
        return zepto.matches(element, selector)
      }))
    },

关于 matches 函数,我在上面文章 Zepto源码二之工具函数中提到过,在此略过

add

添加元素到当前匹配的元素集合中。如果给定content参数,将只在content元素中进行查找,否则在整个document中查找。

add: function(selector,context){
   
// 先调用 $ 函数,将 selector转化成zepto对象,再拼接到现在操作的 zepto 对象上,再去重,将去重结果再转化成zepto对象并返回
    return $(uniq(this.concat($(selector,context))))
    },

is

判断当前元素集合中的第一个元素是否符css选择器。对于基础支持jquery的非标准选择器类似: :visible包含在可选的“selector”模块中。

is: function(selector){
   
      // 先判断传入的是不是css选择器(通常是string形字符串)
      // 如果当前操作的 zepto 对象存在,且有内容,那么用 matches 匹配传入的内容是不是第一个,如果是 返回 true,否则返回 false
      return typeof selector == 'string' ? this.length > 0 && zepto.matches(this[0], selector) : 
      // 如果不存在则尴尬了,只能强行检验传入的selector与当前对象的selector是不是相等,返回比较结果
          selector && this.selector == selector.selector
    },

find

在当对象前集合内查找符合CSS选择器的每个元素的后代元素。如果给定Zepto对象集合或者元素,过滤它们,只有当它们在当前Zept

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值