Zepto.js学习笔记

一、zepto 基础

zepto 是轻量级的 JavaScript 库,专门为移动端定制的框架

zepto 与 jQuery 有类似的 API(“会 jQuery 就会用 zepto”)

zepto官网GitHub 上下载地址

特点

(1)针对移动端

(2)轻量级,压缩版本只有 8kb 左右

(3)响应、执行快

(4)语法、API 大部分同 jQuery 一样,学习难度低,上手快

(5)目前 API 完善的框架中体积最小的一个

hello world

<body>
    <div id='btn'>hello world</div>
    <script type="text/javascript" src="./js/zepto.js"></script>  <!--引入 zepto-->
    <script type="text/javascript" src="./js/touch.js"></script>  <!--引入 移动端触屏事件相关函数-->
    <script type="text/javascript">
        $(function(){
            $('#btn').on('touchstart', function(){
                alert('hello world');
            })
        });
    </script>
</body>

二、zepto 和 jQuery

相同点

(1)都是优秀的 js 函数库

(2)语法、API 大部分都一样(zepto 是按照 jQuery 的思路来设计的)

(3)zepto 相当于 jQuery 的子集

(4)和 jQuery 一样都是以 $ 为核心

和 jQuery 相同的 API

jQuery 核心: $

— 作为函数调用(一般关注参数),参数可以是

function(){}
选择器字符串
DOM 节点
html 字符串

— 作为对象使用(一般关注方法)

$.isArray()
$.ajax() $.get() $.post()
$.each()
...

jQuery 对象:核心函数 $ 调用返回的就是 jQuery 对象,而且是一个伪数组,方法有

append()
find()
show()
...

以上 jQuery 的概念 zepto 同样适用

不同点

(1) attr 和 prop

在 zepto 中用 attr 也可以获取布尔值属性,prop 在读取属性时优先级高于 attr,布尔值属性的读取还是建议用 prop

如对于下拉框 中,选中的选中标签中属性 selected=”selected”

在 jQuery 中
    使用 attr 读取时
    有 selected 属性的返回 selected,没有的返回 undefined
    若用 prop 读取时
    有 selected 属性的返回 true,没有的返回 false,若有多个 selected="selected" 则只有最下面的选项返回为 true
在 zepto 中
    使用 attr 读取时
    有 selected 属性的返回 selected,没有的返回 false
    若用 prop 读取时
    有 selected 属性的返回 true,没有的返回 false,若有多个 selected="selected" 则只有最下面的选项返回为 true,和 jQuery 中相同

注意:zepto 中 removeProp() 方法在 1.2+ 版本才支持

(2)DOM 操作

jQuery 中插入 DOM 元素时添加配置对象(如 id、class 等)不起作用

zepto 中插入 DOM 元素时添加配置对象(如 id、class 等)可以添加进去,并且会直接显示在

<script type="text/javascript" src="./js/zepto.js"></script>
<script type="text/javascript">
    $(function(){
        var $p = $('<p>文本</p>', {
            id:'xxx'
        })
        $('#box').append($p);
    });
</script>

(3)each 方法

在 jQuery 中 $each() 可以遍历数组(以 index,item 的形式)、对象(以 key,value 的形式),但不可以遍历字符串,也意味着不能遍历 json 的对象和数组

在 zepto 中 $each() 可以遍历数组(以 index,item 的形式)、对象(以 key,value 的形式),也可以遍历字符串,也可以以字符串形式遍历 json 的对象和数组

(4)offset()

在 jQuery 中 offset() 获取匹配元素在当前视口的相对偏移量,返回的对象包含 top 和 left 两个整型属性

在 zepto 中 offset() 返回的对象包含 top、left、width、height 四个整型属性,其中 width 和 height 是元素可见区(宽/高 + padding + border)的宽高

(5)height() 和 width()

在 jQuery 中获取宽高的方法:

width() 和 height() ———— content 内容区的宽高,没有单位 px
.css('width')、.css('height') ———— 获取 content 内容区宽高 + padding + border,有单位 px
innerHeight()、innerWidth() ———— 获取 content 内容区宽高 + padding,没有单位
outerHeight()、outerWidth() ———— 获取 content 内容区宽高 + padding + border,没有单位

在 zepto 中获取宽高:

width() 和 height() ———— 根据盒模型取值,获取 content 内容区宽高 + padding + border,没有单位 px
.css('width')、.css('height') ———— 获取 content 内容区宽高,有单位 px
.css('padding') ———— 获取 padding 值,有单位 px
.css('border')、.css('border-width') ———— 获取 border 相关值,有单位 px
没有 innerHeight()、innerWidth()、outerHeight()、outerWidth() 方法

(6)隐藏元素的宽高

在 jQuery 中对于 display:none 的元素使用 .width() 和 .height() 依然可以得到元素宽高

在 zepto 中对于 display:none 的元素使用 .width() 和 .height() 得到结果为 0

(7)事件委托

在 jQuery 中设置事件委托:

(1)$(父元素选择器).delegate(子元素选择器,事件名,回调函数)

(2)$(父元素选择器).on(事件名,子元素选择器,回调函数)

(3)在 1.7 及以下还可以使用 live 函数,但在 1.7 以上已被废除

在 zepto 官网表示已经要废除 live、delegate 等

在 zepto 中委托的事件先被依次放入数组队列里,然后由自身开始往后找直到找到最后,期间符合条件的元素委托的事件都会执行,条件有

(1)委托在同一个父元素,或者触发的元素的事件范围小于同类型事件(冒泡能冒到自身范围)
(2)是同一个事件
(3)委托关联,即操作的类要进行关联
(4)绑定顺序————从当前的代码位置往后看

<head>
    <style>
        .a{
            width:100px;
            height:100px;
            background:red;
        }
        .b{
            width:200px;
            height:200px;
            background:green;
        }
    </style>
</head>
<body>
    <div id='box'>
        <div class="a"></div>
        <div class="b"></div>
    </div>
    <script type="text/javascript" src="./js/zepto.js"></script>  <!--引入 zepto-->
    <script type="text/javascript" src="./js/touch.js"></script>  <!--引入 移动端触屏事件相关函数-->
    <script type="text/javascript">
        $('#box').on('touchstart', '.a', function(){
            alert('a触发的事件');
            $(this).removeClass().addClass('b'); //和 b 关联
        })
        $('#box').on('touchstart', '.b', function(){
            alert('b触发的事件');
            $(this).removeClass().addClass('a');
        })
    </script>
</body>

上述代码中当点击 a 的 div 时,会弹出 “a触发的事件”、“b触发的事件”,但 div 的样式没有变化,而当点击 b 的 div 时,会弹出 “b触发的事件”,div 的样式变为 a 类的 div

— 若把 a 绑定的事件中 $(‘#box’) 改为 $(‘#body’) 就不会发生这种情况,因为不符合第(1)个条件

— 若把 a 绑定的事件中 touchstart 改为 click 就不会发生这种情况,因为不符合第(2)个条件

— 若把 a 绑定的事件中 $(this).removeClass().addClass('b'); 删除就不会发生这种情况,因为不符合第(3)个条件

— 若把 a 绑定的事件相关代码移到 b 绑定的事件之后就不会发生这种情况,因为不符合第(4)个条件

而点击 a 样式没有变化(没有按预期变为 b)是因为当 class 变为 b 后会启动一个新线程用于重排,但 js 代码执行比重排快,此时会执行 b 绑定的事件,且 alert 会阻断代码执行,而当关闭 alert 窗口后 class 又变回 a 因此样式没有变化

(8)touch Event

同 jQuery 类似的事件:

on() 绑定事件处理程序
off() 移除用目标元素 on 绑定的事件处理程序
one() 为每一个匹配元素的特定事件(如 click)绑定一个一次性事件处理函数,只执行一次
bind() 为每个匹配元素的特定事件绑定事件处理函数,可同时绑定多个事件,也可自定义事件
trigger() 触发由 bind 定义的事件(通常是自定义事件)
unbind() bind 的反向操作,删除匹配元素绑定的 bind 事件

如自定义事件

$('#btn').bind('myTouch',function(){
    alert('xx');
})
$('#btn').trigger('myTouch')

zepto touch 方法

tap() 点击事件,利用在 document 上绑定 touch 事件来模拟 tap 事件的,并且 tap 事件会冒泡到 document 上

singleTap() 单击事件

doubleTap() 双击事件

longTap() 当一个元素被按住超过 750ms 触发

swipe、swipeLeft、swipeRight、swipeUp、swipeDown 当元素被划过(同一个方向大于 30px)时触发(可选择给定的方向在一个方向滑动大于 30px 即为滑动,否则算点击)

注意:在给元素设置滑动事件时需要通过 touch-action:none; 将默认的元素上滑动翻页行为禁掉

<head>
    <style>
        #btn{
            touch-action: none;
        }
    </style>
</head>
<body>
    <div id='btn'>xxx</div>
    <script type="text/javascript" src="./js/zepto.js"></script>  <!--引入 zepto-->
    <script type="text/javascript" src="./js/touch.js"></script>  <!--引入 移动端触屏事件相关函数-->
    <script type="text/javascript">
        $('#btn').swipe(function(){
            alert('xxx');
        })
    </script>
</body>

三、zepto 事件机制

zepto 有自己的一套事件机制,并对不同的浏览器做了兼容的内部封装处理

新版本的 zepto 中已经舍弃了 bind、delegate、die(live 的反向操作),同样 jQuery 中舍弃了 live 等

现在统一使用 on、off 标准事件来绑定事件

四、form 表单

serialize()

在 Ajax post 请求中将用作提交的表单元素的值编译成 URL-encoded 字符串 ———— name=value

不能使用的表单元素、buttons、未选中的 radio buttons、checkboxs 将会被跳过

serializeArray()

将用作提交的表单元素的值编译成拥有 {name,value} 对象组成的数组

不能使用的表单元素、buttons、未选中的 radio buttons、checkboxs 将会被跳过

submit()

为 “submit” 事件绑定一个处理函数,或者触发元素上的 “submit” 事件

当参数 function 没有给出时,触发当前表单 “submit” 事件,并且执行默认的提交表单行为,除非阻止默认行为

<form method="post">
    <input type="text" name="val" value="aaa">
    <input type="password" name="pw" value="123">
    <input type="checkbox" name="item" checked="checked">
    <input type="submit" value="按钮" name="btn">
</form>
<script type="text/javascript" src="./js/zepto.js"></script>
<script type="text/javascript" src="./js/touch.js"></script>
<script type="text/javascript">
    $(function(){
        var result = $('form').serialize();
        console.log(result);  //输出 val=aaa&pw=123&item=on
        $('form').submit(function(event){
            event.preventDefault();  //取消默认提交
            console.log("暂时不想提交")
        })
    })
</script>

五、ajax 细节剖析

abort() 在 zepto 中取消 ajax 请求

问题:点击获取验证码的按钮,用户十秒后可再次获取,当十秒过后第一次请求没有返回,然后因为网速好或其他原因,两次请求同时返回该如何解决?

用户再次点击时取消之前的请求,注意 disabled 禁止用户点击操作按钮、表单项,但只是针对 click 事件,并没有对 touch 事件做处理

$(function(){
    var isSend = false;  //通过该变量控制间隔相应时间后才能再次点击
    var xmlHttp = null;
    $('#btn').on('touchstart',function(){
        if(isSend){  //用户点击失效
            return;
        }
        isSend = true;
        $(this).css('background','gray');
        setTimeout(function(){
            $('#btn').css('background','red');
            isSend = false;
        },2000);
        if(!xmlHttp){  //用户没发过请求
            xmlHttp = sendXml();
        }else{
            xmlHttp.abort();  //取消上一次请求
            xmlHttp = sendXml();
        }
    })
});
function sendXml(){
    var xmlHttp = $.ajax({
        "method":'GET',
        "url":'http://127.0.0.1'
        dataType:'json';
        success: function(data){
            console.log(data);
        },
        error: function(error){
            console.log(error);
        }
    })
    return xmlHttp;
}