Zepto.js学习笔记
一、zepto 基础
zepto 是轻量级的 JavaScript 库,专门为移动端定制的框架
zepto 与 jQuery 有类似的 API(“会 jQuery 就会用 zepto”)
特点
(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;
}