zepto的构造器$

在zepto中,通过$来构造对象

$ = function(selector, context){
    return zepto.init(selector, context)
  }

由该函数,实际上,在调用$函数时相当于调用init方法,接下来看init函数:

zepto.init = function(selector, context) {
    var dom
    // If nothing given, return an empty Zepto collection
    //返回一空的zepto对象
    if (!selector) return zepto.Z()
    // Optimize for string selectors
    else if (typeof selector == ‘string‘) {
      //消除空格
      selector = selector.trim()
      //这里根据不同的情况返回dom
      if (selector[0] == ‘<‘ && fragmentRE.test(selector))
        dom = zepto.fragment(selector, RegExp.$1, context), selector = null
      // If there‘s a context, create a collection on that context first, and select
      // nodes from there
      else if (context !== undefined) return $(context).find(selector)
      // If it‘s a CSS selector, use it to select nodes.
      else dom = zepto.qsa(document, selector)
    }
    // If a function is given, call it when the DOM is ready
    else if (isFunction(selector)) return $(document).ready(selector)
    // If a Zepto collection is given, just return it
    else if (zepto.isZ(selector)) return selector
    else {
      // normalize array if an array of nodes is given
      if (isArray(selector)) dom = compact(selector)
      // Wrap DOM nodes.
      else if (isObject(selector))
        dom = [selector], selector = null
      // If it‘s a html fragment, create nodes from it
      else if (fragmentRE.test(selector))
        dom = zepto.fragment(selector.trim(), RegExp.$1, context), selector = null
      // If there‘s a context, create a collection on that context first, and select
      // nodes from there
      else if (context !== undefined) return $(context).find(selector)
      // And last but no least, if it‘s a CSS selector, use it to select nodes.
      else dom = zepto.qsa(document, selector)
    }
    // create a new Zepto collection from the nodes found
    return zepto.Z(dom, selector)
  }; 

先来看一下当传入的是一个html标签的字符串时的构造过程:

if (selector[0] == ‘<‘ && fragmentRE.test(selector))
        dom = zepto.fragment(selector, RegExp.$1, context), selector = null
fragmentRE = /^\s*<(\w+|!)[^>]*>/;

fragmentRE是一个匹配普通标签<xxx>的表达式,关键是zepto.fragment()函数。

该函数传入三个参数,在这里传入的分别是selector, RegExp.$1, context,RegExp.$1储存的是当前调用的正则表达式匹配的第一个子表达式。即当我们传入<span>时,其值为span,接下来可以看fragment函数。

zepto.fragment = function(html, name, properties) {
    var dom, nodes, container

    // A special case optimization for a single tag
    //创建一个元素
    if (singleTagRE.test(html)) dom = $(document.createElement(RegExp.$1))

    if (!dom) {
      //将html转换为标签,$1$2表示的是匹配的第一个和第二个子表达式
      if (html.replace) html = html.replace(tagExpanderRE, "<$1></$2>")

      if (name === undefined) name = fragmentRE.test(html) && RegExp.$1
      //创建一个name元素  根据是否为表格元素对其进行下一步操作
      if (!(name in containers)) name = ‘*‘

      container = containers[name]
      //将标签插入name元素
      container.innerHTML = ‘‘ + html
      //$.each函数最终返回传入的第一个数组参数
      dom = $.each(slice.call(container.childNodes), function(){
        container.removeChild(this)
      })
    }
    if (isPlainObject(properties)) {
      //将dom转成zepto对象
      nodes = $(dom)
      $.each(properties, function(key, value) {
        if (methodAttributes.indexOf(key) > -1) nodes[key](value)
        else nodes.attr(key, value)
      })
    }
    return dom
  }

在这个函数中,有两个正规表达式,分别是tagExpanderRE和singleTagRE

tagExpanderRE = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig;
singleTagRE = /^<(\w+)\s*\/?>(?:<\/\1>|)$/

singleTagRE匹配的是单个的<span></span>诸如此类的标签,而tagExpanderRE匹配的是自闭合标签,如<span/>,但不能是img之类,并将其转成<span><span/>;

从函数中,如果匹配的是单个的html标签,则直接创建该标签并$实例化,将其转变为一个zepto对象,如果匹配的是另一种情况,即将dom转成一个存储这些节点的数组。

然后就是最后一个条件判断了:

           

if (isPlainObject(properties)) {
      //将dom转成zepto对象
      nodes = $(dom)
      $.each(properties, function(key, value) {
        if (methodAttributes.indexOf(key) > -1) nodes[key](value)
        else nodes.attr(key, value)
      })
    }

先看一下isPlainObject函数,该函数判断是否为一个纯对象:

function isPlainObject(obj) {
    return isObject(obj) && !isWindow(obj) && Object.getPrototypeOf(obj) == Object.prototype
  }    

 主要的判断在于Object.getPrototypeOf(obj) == Object.prototype;不同的参数调用getPrototypeOf(obj)返回的值不同:

条件判断里的代码需要注意一点,即将dom转成zepto对象,

  

时间: 2024-10-12 17:08:29

zepto的构造器$的相关文章

zepto与jquery冲突的解决

问题出现的背景: 在light7框架下搭建的触屏版项目中,要拓展一个投票系统,其中投票系统有一个比较完善的上传组件,但是此组件是依赖zepto的,而原来的项目是依赖jQuery的,所以就会遇到冲突的问题: 解决方法1: jquery有一个方法叫noConflict() ,可以把jquery的$改掉. var jq=$.noConflict(); 这个时候用jq来代替jquery的$吧. 解决方法2: zepto的符号改掉 window.zp=window.Zepto = Zepto 在zepto

zepto事件

1.zepto的定义 Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api 2.zepto与jq的区别 ①相同点:Zepto最初是为移动端开发的库,是jQuery的轻量级替代品,因为它的API和jQuery相似,而文件更小:zepto的API大部分都能和jQuery兼容,所以用起来极其容易 ②不同点: (1).针对移动端程序,Zepto有一些基本的触摸事件可以用来做触摸屏交互(tap事件.swipe事件) (2),Dom操作的区别:添加id时jQ

zepto 基础知识(6)

101.$.ajax $.ajax(options) 类型:XMLttpRequest 执行Ajax请求.他可能是本地资源,或者通过支持HTTP access control的浏览器 或者通过 JSONP来实现跨域. 选项: type(默认: “GET”):请求方法 (“GET”, “POST”, or other) url (默认: 当前地址):发送请求的地址 data (默认:none):发送到服务器的数据:如果是GET请求,它会自动被作为参数拼接到url上.非String对象将通过 $.p

zepto的touch模块解决click延迟300ms问题以及点透问题的详解

大家都知道移动端的click事件会延迟300ms触发,这时大家可以使用zepto的touch模块,里面定义了一个tap事件,通过绑定tap事件,可以实现点击立即触发的功能. 那么,它的tap事件是怎么实现的呢?这是我们要解决的第一个问题. 第二个问题,大家都知道zepto的tap事件会有点透的问题,那么,点透如何出现,点透为什么会出现,点透问题如何解决等,这是我们要解决的第二个问题. 我们先来看tap事件是如何实现的? 查看touch.js代码,在最后的代码中有以下代码: ;['swipe',

zepto实现轮播图

zepto是一个移动端的框架,语法几乎跟jQuery一样, 首先需要引入你需要的插件,需要什么就引入什么. <!-- 导入zepto --> <script type="text/javascript" src='js/zepto.js'></script> <!-- touch事件 --> <script type="text/javascript" src='js/touch.js'></scri

读Zepto源码之样式操作

这篇依然是跟 dom 相关的方法,侧重点是操作样式的方法. 读Zepto源码系列文章已经放到了github上,欢迎star: reading-zepto 源码版本 本文阅读的源码为 zepto1.2.0 内部方法 classRE classCache = {} function classRE(name) { return name in classCache ? classCache[name] : (classCache[name] = new RegExp('(^|\\s)' + name

zepto

Zepto是一个轻量级的针对现代高级浏览器的JavaScript库, 它与jquery有着类似的api. 如果你会用jquery,那么你也会用zepto. 需要注意的是Zepto的一些可选功能是专门针对移动端浏览器的:因为它的最初目标在移动端提供一个精简的类似jquery的js库. 核心方法 $() $('div') //=> 所有页面中得div元素 $('#foo') //=> ID 为 "foo" 的元素 // 创建元素: $("<p>Hello&

zepto 事件分析2($.on)

这里主要分析zepto事件中的$.on函数,先看一下该函数的代码 $.fn.on = function(event, selector, data, callback, one){ var autoRemove, delegator, $this = this if (event && !isString(event)) { //多个事件下的处理 $.each(event, function(type, fn){ $this.on(type, selector, data, fn, one

Zepto整体概况

var Zepto = (function(){ var zepto = {},$; zepto.Z = function(dom, selector) { return new Z(dom,selector) } zepto.init = function(selector,context){ .... return zepto.Z(dom, selector) } $ = function(selector,context){ return zepto.init(selector,conte