Zepto
一.Helloworld
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>zepto入门</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
#btn{
width: 200px;
height: 200px;
background: #FFFF00;
margin: 0 auto;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<!--
* 什么是zepto.js
概念: 移动端开发框架,是jquery的轻量级代替品;API及语句同jquery相似,但文件更小(可压缩至8KB)。
是目前功能完备的库中,最小的一个。
* zepto.js特点
1、针对的是移动端
2、轻量级,压缩版本只有8KB
3、语法大部分同jquery一样,学习成本低,上手快。
4、响应,执行快。
5、同jquery一样以$作为核心函数和核心对象。
-->
<div id="btn">我是一个按钮</div>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
$('#btn').on('touchstart',function(){
alert('我是zepto')
});
$('body').append($('<p>我是新添加的p标签</p>'));
})
</script>
</body>
</html>
二.与jQuery相同的API
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>common</title>
<style type="text/css">
.box1{
width: 200px;
height: 200px;
background:#FF0000;
}
.box2{
width: 200px;
height: 200px;
background:#FF00FF;
}
.box3{
width: 200px;
height: 200px;
background: green;
}
#dis{
display: none;
}
</style>
</head>
<body>
<!--
* 共同点:
jquery:
* 核心函数$
1、作为函数使用(参数)
1.function
2.html字符串
3.DOM code
4.选择器字符串
2、作为对象调用(方法)
1.$.ajax() $.get() $.post()
2.$.isArray()
$.each()
$.isFunction()
$.trim()
......
* jquery对象
概念:jquery核心函数$()调用返回的对象就是jquery对象的数组(可能有只有一个);
使用:
1.addClass()
2.removeClass()
3.show()
4.find()
zepto:
以上jquery的特性zepto同样适用
-->
<div class="box1">我是box1</div>
<div class="box2">我是box2</div>
<div class="box3">
<p>111</p>
<p>222</p>
<p>333</p>
</div>
<div id="dis">隐藏的元素</div>
<script src="../../js/zepto.js"></script>
<script src="../../js/touch.js"></script>
<script type="text/javascript">
$(function () {
$('.box1').on('touchstart',function () {
$(this).addClass('box2');
});
$('.box2').on('touchstart',function () {
$('#dis').show();
});
$('.box3').on('touchstart',function () {
$(this).find('p').css('background','red');
})
})
</script>
</body>
</html>
三.事件委托
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>jquery_事件委托</title>
<style type="text/css">
#box{
width: 400px;
background: green;
}
.a{
width: 200px;
height: 200px;
background: #FF0000;
}
.b{
width: 100px;
height: 100px;
background: #F0f;
}
</style>
</head>
<body>
<div id="box">
<div class="a">a的事件委托</div>
<br />
<br />
<br />
<div class="b">b的事件委托</div>
<br />
<br />
<br />
<div id="a">#a事件委托</div>
<p>Click me!</p>
</div>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
console.log($('.a').length);
//1.7以后已经不 支持live了。
// $('#a').live('click',function(){
// alert('a');
// })
// $('#box').delegate('.a','click',function(){
// alert('delegate');
// })
//在jquery中事件委托只是找相应的event.target触发元素进行的回调函数执行,其他的并不关心。
$('#box').on("click",'.a',function(){
alert('a事件');
$(this).removeClass('a').addClass('b');
});
$('#box').on("click",'.b',function(){
alert('b事件');
$(this).removeClass('b').addClass('a');
});
$('#box').append('<div class="a" style="font-size: 30px;">我是新添加的div</div>')
})
</script>
</body>
</html>
四.zepto事件委托
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto_事件委托</title>
<style type="text/css">
#box{
width: 400px;
background: green;
}
.a{
width: 200px;
height: 200px;
background: #FF0000;
}
.b{
width: 100px;
height: 100px;
background: #F0f;
}
</style>
</head>
<body>
<div id="box">
<div class="a">a 的事件委托</div>
<br />
<br />
<br />
<div class="b">b的事件委托</div>
<br />
<br />
<br />
<div id="a">#a的事件委托</div>
<p>Click me!</p>
</div>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../../../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//在zepto的官网表示已经废除了live,delegate等。
// $('.a').live('click',function(){
// alert('a')
// })
//* 坑!!!!
/*
* ---在zepto中事件委托
委托的事件先被依次放入数组队列里,然后由自身开始往后找直到找到最后,期间符合条件的元素委托的事件都会执行。
1、委托在同一个父元素,或者触发的元素的事件范围小于同类型事件(冒泡能冒到自身范围)
2、同一个事件
3、委托关联 操作的类要进行关联
4、绑定顺序---从当前的位置往后看
*/
$('#box').on("click",'.a',function(){
alert('a事件');
$(this).removeClass('a').addClass('b');
});
$('#box').on("click",'.b',function(){
alert('b事件');
$(this).removeClass('b').addClass('a');
});
$('#box').append($('<p>我是新添加的p标签</p>',{class:'a'}));
})
</script>
</body>
</html>
五.隐藏元素宽高
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
#box{
display: none;
width: 200px;
height: 200px;
border:1px solid #ff0;
}
</style>
</head>
<body>
<!--
jquery可以获取隐藏元素的宽高
-->
<div id="box"></div>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
console.log($('#box').width());
console.log($('#box').height());
});
</script>
</body>
</html>
六.zepto
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>zepto</title>
<style type="text/css">
#box{
display: none;
width: 200px;
height: 200px;
border: 1px solid #ff0;
}
</style>
</head>
<body>
<!--
zepto无法获取隐藏元素宽高
-->
<div id="box">hello</div>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
console.log($('#box').width());
console.log($('#box').height());
});
</script>
</body>
</html>
七.attr和prop
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>jquery</title>
</head>
<body>
<select style="font-size: 25px;">
<option value="name">科比</option>
<option value="name">韦德</option>
<option value="name" selected="selected">邓肯</option>
<option value="name">吉诺比利</option>
<option value="name" selected="selected">艾弗森</option>
</select>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//attr与prop的区别
/*
* 1、prop多用在标签的固有属性,布尔值属性。比如:a标签的href,class,selected等。
* 2、attr多用在自定义属性上。
* 3、在jquery中如果用attr去获取布尔值属性且该布尔值属性在标签体内没有定义的时候,会返回undefined
*/
$('option').each(function (index, item) {
console.log(index, item.innerHTML);
console.log($(this).attr('selected'));//没有定义获取到的是undefined
console.log($(this).prop('selected'));//4false 1true
});
});
</script>
</body>
</html>
八.zepto
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto_selected</title>
</head>
<body>
<select>
<option value="name">科比</option>
<option value="name">韦德</option>
<option value="name" selected="selected">邓肯</option>
<option value="name">吉诺比利</option>
<option value="name" selected="selected">艾弗森</option>
</select>
<button id="btn">按钮</button>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../../../js/touch.js"></script>
<script type="text/javascript">
//在zepto中用attr也可以获取布尔值属性.
//prop在读取属性的时候优先级高于attr,布尔值属性的读取还是建议用prop
//坑!------zepto中removeProp()的方法。在1.2及以上才支持。
$(function () {
$('option').each(function (index, item) {
//console.log($(this).attr('selected'));
console.log($(this).prop('selected'));
});
$('#btn').click(function () {
$(this).prop('disabled', 'true');
setTimeout(function () {
$('#btn').removeAttr('disabled');
}, 2000);
});
});
</script>
</body>
</html>
九.DOM操作
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
<style type="text/css">
#insert{
background: #ff0;
}
</style>
</head>
<body>
<!--
jquery中插入DOM元素的时候添加配置对象(属性选择器:id,class。。。)的时候不会显示;
-->
<div id="box"></div>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
var $insert = $('<p>我是新添加的p标签</p>', {
id:'insert'
});
$('#box').append($insert)
});
</script>
</body>
</html>
十.zepto操作DOM
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto</title>
<style type="text/css">
#insert{
background: #ff0;
}
.insert{
width:200px;
}
</style>
</head>
<body>
<!--
插入DOM元素的时候添加配置对象的时候可以添加进去,并且添加的配置对象的内容会直接反应在标签属性内,且可以操作,影响对应的DOM元素。
-->
<div id="box"></div>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
var $insert = $('<p>我是新添加的p标签</p>', {
id:'insert',
class:'insert'
});
$('#box').append($insert)
});
</script>
</body>
</html>
十一.each方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jquery_each</title>
</head>
<body>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//$.each(collection, function(index, item){ ... })
//可以遍历数组,以index,item的形式,
//可以遍历对象,以key-value的形式
//不可以遍历字符串。
//不可以遍历json字符串
var arr = [1,'a',3,'b',5];
var obj = {name:'tom',age:13};
//遍历数组,
$.each(arr, function(index,item) {
console.log(index + '-' + item);
});
$.each(obj, function(key,value) {
console.log(key + '-' + value);
});
//不可以遍历字符串。
var str = 'adfdfdf';
$.each(str,function(index){
console.log(index);
})
})
</script>
</body>
</html>
十二.zepto的each方法
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>zepto_each</title>
</head>
<body>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//$.each(collection, function(index, item){ ... })
//可以遍历数组,以index,tiem的形式,
//可以遍历对象,以key-value的形式,
//可以遍历字符串。
var arr = [1,'a',3,'b',5];
var obj = {name:'tom',age:13};
$.each(arr, function(index,item) {
console.log(index + '-' + item);
});
$.each(obj, function(key,value) {
console.log(key + '-' + value);
});
var str = 'abcdef';
//可以遍历字符串,同对数组的遍历方法一样以index-item的形式。
$.each(str, function(index,item) {
console.log(index + '-' + item);
});
})
</script>
</body>
</html>
十三.offset
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>jquery_offset的区别</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
width: 200px;
height: 200px;
position: relative;
left: 50px;
top: 100px;
font-size: 22px;
background: #ff0;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<!--
1、获取匹配元素在当前视口的相对偏移。
2、返回的对象包含两个整型属性:top 和 left。此方法只对可见元素有效。
-->
<div id="box">新年快乐,大吉大利</div>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
var $offset = $('#box').offset();
console.log($offset);
console.log($offset.top);
//获取width,height时为undefined
console.log($offset.width);
})
</script>
</body>
</html>
十四.zepto的offset
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto_offset的区别</title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
width: 200px;
height: 200px;
position: relative;
left: 50px;
top: 50px;
font-size: 22px;
background: #FF0000;
text-align: center;
line-height: 200px;
}
</style>
</head>
<body>
<!--
* offset()
1、获得当前元素相对于视口的位置。
2、返回一个对象含有: top, left, width和height(获取的宽高是盒模型可见区域的宽高)
-->
<div id="box">新年快乐,大吉大利</div>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
var $offset = $('#box').offset();
console.log($offset);
console.log($offset.left);
console.log($offset.width);
})
</script>
</body>
</html>
十五.width()和height()的区别
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>jquery</title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background: #f00;
margin: 10px;
padding: 10px;
border: 3px solid #f0f;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="../../../js/jquery-1.10.1.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
/*
* jquery获取宽高的方法
1、width(),height()---content内容区的宽高,没有单位px;
2、.css('width')----可以获取content内容区的宽高,padding,border的值,有单位px;
3、innerHeight(),innerWidth()---outerHeight(),outerWidth()来获取
* */
$(function(){
//jquery中width(),height(),.css()返回的始终是content区域的宽高
console.log($('#box').width());
console.log($('#box').height());
console.log($('#box').css('width'));
//可以通过css()获取padding,border的值
console.log($('#box').css('padding'));
console.log($('#box').css('border-width'));
//也可以利用innerHeight(),outerHeight(),innerWidth(),outerWidth()等来获取padding和border的值
console.log($('#box').innerHeight());
console.log($('#box').outerHeight()+'outerHeight');
})
</script>
</body>
</html>
十六.zepto
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto</title>
<style type="text/css">
#box{
width: 200px;
height: 200px;
background: #f00;
margin: 10px;
padding: 10px;
border: 1px solid #ff0;
}
</style>
</head>
<body>
<div id="box"></div>
<script src="../../../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//zepto用width(),height()是根据盒模型决定的,并且不包含单位PX
//包含padding的值,border的值
//zepto中没有innerHeight(),innerWidth()---outerHeight(),outerWidth()
console.log($('#box').width());
console.log($('#box').height());
//用.css('width')获取的是content的宽高。
console.log($('#box').css('width'));
//* 单独获取padding,border的值
console.log($('#box').css('padding'));
console.log($('#box').css('border-width')+'border');
})
</script>
</body>
</html>
十七.同jQuery类似事件touch Event
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>同jquery类似事件</title>
<style type="text/css">
.btn2{
width: 100px;
height: 100px;
background: #f0f;
}
</style>
</head>
<body>
<!--
on() 绑定事件处理程序
off() 方法移除用目标on绑定的事件处理程序。
bind() 为每个匹配元素的特定事件绑定事件处理函数,可同时绑定多个事件,也可以自定义事件。
one() 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数。只执行一次。
trigger() 触发有bind定义的事件(通常是自定义事件)
unbind() bind的反向操作,删除匹配元素所绑定的bind事件。
-->
<button id="btn1">按钮1</button>
<div class="btn2">按钮2</div>
<button id="btn3">按钮3</button>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
$('#btn1').on('touchstart',function(){
alert('我是btn1');
});
// $('#btn1').off('click');
//bind
$('.btn2').bind('touchstart touchmove',function(){
$(this).toggleClass("btnSty")
});
//one
$('#btn3').one('click',function(){
alert('我是btn3')
});
//trigger 自动执行
$('#btn1').bind('myTouch',function(event,a,b){
alert('我是由trigger触发的btn');
console.log(a + ' ' + b);
});
$('#btn1').trigger('myTouch',['hello','world']);
//unbind
$('#btn2').unbind('touchmove');
})
</script>
</body>
</html>
十八.zepto
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>zepto_touch</title>
<style type="text/css">
*{
touch-action: none;
}
.box{
width: 100px;
height: 100px;
background: #FFFF00;
margin: 0 auto;
text-align: center;
line-height: 100px;
}
.btn{
width: 100px;
height: 50px;
background: #FF0000;
border-radius: 10px;
margin: 0 auto;
}
</style>
</head>
<body style="height: 1000px;">
<!--
* zepto touch方法
* tap()点击事件 利用在document上绑定touch事件来模拟tap事件的,并且tap事件会冒泡到document上
* singleTap() 点击事件
* doubleTap() 双击事件
* longTap() 当一个元素被按住超过750ms触发。
* swipe, swipeLeft, swipeRight, swipeUp, swipeDown — 当元素被划过(同一个方向滑动距离大于30px)时触发。(可选择给定的方向)
在一个方向滑动大于30px即为滑动。否则算点击。
-->
<div id="box" class="box">按钮1</div>
<br />
<div id="box2" class="box">按钮2</div>
<br />
<div id="box3" class="box">按钮3</div>
<button id="btn" class="btn">button</button>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
//tap()点击事件---真机测没问题
// $('#box').tap(function () {
// alert('tap事件');
// });
$('#box').on('tap',function () {
alert('tap事件');
});
//singleTap()单击事件
$('#box2').singleTap(function () {
alert('我单击了一下');
});
//doubleTap() 双击事件
$('#box2').doubleTap(function () {
alert('我双击了一下');
});
//longTap()长按事件----按住屏幕时间超过750ms触发
$('#box3').longTap(function () {
alert('我长按了一下box3');
});
//swipe()滑动事件---在同一个方向连续滑动超过30px
$('#btn').swipe(function () {
alert('我滑动了超过30px');
});
$('#btn').swipeLeft(function () {
alert('我向左滑动了');
});
});
</script>
</body>
</html>
十九.事件处理机制
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>Event</title>
<style type="text/css">
.btn{
width: 200px;
height: 200px;
background: #ff0;
}
</style>
</head>
<body>
<div id="box" class="btn">Event</div>
<div id="box1">
<p>1111</p>
<p>2222</p>
<p>3333</p>
</div>
<div id="box2" class="btn"></div>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
/*
* zepto有自己的一套事件机制,并且对不同的浏览器做了兼容的内部封装处理。
* 1、像新版本的zepto中已经舍弃了bind,delegate,die,同样jquery中舍弃了live,die等。
* 2、现在统一使用on,off标准事件来绑定事件。
*/
$(function(){
//简单绑定
$('#box').on('touchstart',function(){
alert('ddd');
});
//事件委托
$('#box1').on('touchstart','p',function(){
alert($(this).text());
});
//解除绑定事件
//$('#box').off('touchstart');
//一次函数
$('#box2').one('touchstart',function(){
alert('我就执行一次');
});
})
</script>
</body>
</html>
二十.form
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title></title>
</head>
<body>
<!--
1、serialize()
* 在Ajax post请求中将用作提交的表单元素的值编译成 URL-encoded 字符串。---key(name)/value
2、serializeArray()
* 将用作提交的表单元素的值编译成拥有name和value对象组成的数组。
* 不能使用的表单元素,buttons,未选中的radio buttons/checkboxs 将会被跳过。
3、submit()
* 为 "submit" 事件绑定一个处理函数,或者触发元素上的 "submit" 事件。
* 当参数function没有给出时,触发当前表单“submit”事件,并且执行默认的提交表单行为,除非阻止默认行为。
-->
<form>
<input type="password" name="pw" value="123"/>
<input type="text" name="val" value="kobe"/>
<input type="checkbox" checked="checked" name="rember"/>
<input type="submit" value="按钮" name="anniu"/>
</form>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function(){
//serialize()
var list = $('form').serialize();
console.log(list);
//serializeArray()
var listArr = $('form').serializeArray();
console.log(listArr);
//submit()
$('form').submit(function(e){
e.preventDefault();
var data = $(this).serialize();
console.log(data);
})
})
</script>
</body>
</html>
二十一.AJAX 案例剖析
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>ajax容易忽视的重点</title>
<style type="text/css">
#btn{
width: 200px;
height: 200px;
background: red;
border-radius: 20px;
text-align: center;
line-height: 200px;
font-size: 30px;
}
</style>
</head>
<body>
<!--
* 如何废除一个ajax请求 ----abort()方法
需求:点击获取验证码的按钮,用户十秒时候可以再次获取,当十秒过后第一次请求没有返回,用户再次点击获取
然后因为网速好或者其他原因,两次请求同时返回,该怎么解决
* disabled属性 设置表单项或者按钮不可再点击或者操作;但是只是针对click事件,而并没有针对touch事件作出处理。
-->
<button id="btn">按钮</button>
<script src="../js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/touch.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
$(function () {
var xmlHttp = null;//初始化xmlHttp对象
var isSend = false;//初始化判断按钮是否可以点击
$('#btn').on('touchstart', function () {
if(isSend === true){//如果不能点击,直接返回
return;
}
$(this).css('background', 'gray');
isSend = true;//修改为不能点击
if(xmlHttp === null){//如果用户首次点击,发送请求
xmlHttp = sendXmlHttp();
}else{
xmlHttp.abort();//再次点击的时候取消上一次请求
xmlHttp = sendXmlHttp();//再次发送最新的请求
}
setTimeout(function () {
$('#btn').css('background', 'red');
isSend = false;//2s以后用户可以再次点击
}, 2000);
});
//发送ajax请求的函数;
function sendXmlHttp() {
var xmlHttp = null;
xmlHttp = $.ajax({
type : 'GET',
url : 'http://localhost:3000/',
dataType : 'json',
success : function (msg) {
console.log(msg);
},
error : function (error) {
console.log(error);
}
});
return xmlHttp;
}
});
</script>
</body>
</html>
二十二.实战练习
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>尚硅谷_zepto实战</title>
<link rel="stylesheet" type="text/css" href="css/reset.css"/>
<link rel="stylesheet" type="text/css" href="css/index.css"/>
<link rel="stylesheet" type="text/css" href="css/animation.css"/>
</head>
<body>
<div id="container">
<div class="page page-1-1 page-current">
<img class="img_1 pt-page-moveFromTop" src="img/cover.png" alt="" />
<img class="img_2 pt-page-moveFromLeft" src="img/wording_cover.png" alt="" />
<img class="img_3 common_img pt-page-moveIconUp" src="img/icon_up.png" alt="" />
</div>
<div class="page page-2-1 hide">
<img class="img_1 hide pt-page-moveFromBottom" src="img/wording.png" />
<img class="img_2 hide pt-page-moveCircle" src="img/circle.png" />
<img class="img_3 hide pt-page-moveFromLeft" src="img/people.png" />
<img class="img_4 hide pt-page-scaleUp" src="img/dot1.png" />
<img class="img_5 hide pt-page-scaleUp" src="img/check_develop.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
<img class="img_7 hide pt-page-scaleUp" src="img/floating_develop.png" />
</div>
<div class="page page-2-2 hide">
<img class="img_1 hide pt-page-flipInLeft" src="img/introduction.png" />
<img class="img_2 hide pt-page-flipInLeft" src="img/btn_develop.png" />
<img class="img_3 hide pt-page-flipInLeft" src="img/dot2.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
</div>
<div class="page page-3-1 hide">
<img class="img_1 hide pt-page-moveFromBottom" src="img/wording_design.png" />
<img class="img_2 hide pt-page-moveCircle" src="img/circle-design.png" />
<img class="img_3 pt-page-moveFromBottom hide" src="img/people_design.png" />
<img class="img_4 hide pt-page-scaleUp" src="img/dot1.png" />
<img class="img_5 hide pt-page-scaleUp" src="img/check_design.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
<img class="img_7 hide pt-page-scaleUp" src="img/floating_design.png" />
</div>
<div class="page page-3-2 hide">
<img class="img_1 hide pt-page-flipInLeft" src="img/introduction_design.png" />
<img class="img_2 hide pt-page-flipInLeft" src="img/btn_design.png" />
<img class="img_3 hide pt-page-flipInLeft" src="img/dot2.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
</div>
<div class="page page-4-1 hide">
<img class="img_1 hide pt-page-moveFromBottom" src="img/wording_production.png" />
<img class="img_2 hide pt-page-moveCircle" src="img/circle-production.png" />
<img class="img_3 pt-page-moveFromRight hide" src="img/people_production.png" />
<img class="img_4 hide pt-page-scaleUp" src="img/dot1.png" />
<img class="img_5 hide pt-page-scaleUp" src="img/check_production.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
<img class="img_7 hide pt-page-scaleUp" src="img/floating_production.png" />
<img class="img_8 hide pt-page-scaleUp" src="img/pic_shadow_production.png" />
</div>
<div class="page page-4-2 hide">
<img class="img_1 hide pt-page-flipInLeft" src="img/introduction_production.png" />
<img class="img_2 hide pt-page-flipInLeft" src="img/btn_production.png" />
<img class="img_3 hide pt-page-flipInLeft" src="img/dot2.png" />
<img class="img_6 hide common_img pt-page-moveIconUp" src="img/icon_up.png" />
</div>
<div class="page page-5-1 hide">
<img class="img_1 hide pt-page-rotateCubeBottomIn" src="img/pic_back.png" />
<img class="img_2 hide pt-page-rotateCubeTopIn" src="img/btn_join.png" />
</div>
</div>
<script src="js/zepto.js" type="text/javascript" charset="utf-8"></script>
<script src="js/touch.js" type="text/javascript" charset="utf-8"></script>
<script src="js/index.js" type="text/javascript" charset="utf-8"></script>
</body>
</html>
index.css
body{
width: 100%;
height:100%;
}
*{
touch-action: none;
}
#container{
width:100%;
height: 100%;
position: absolute;
}
/*定义每个div的宽高及定位!!不能使用relative因为父元素高度没有办法被脱离文档流的子元素撑开*/
.page{
width: 100%;
height: 100%;
position: absolute;
}
.hide{
display: none;
}
.page-current{
z-index: 2;
}
.common_img{
height: auto;
width: 25px;
position: absolute;
top: 92%;
left: 50%;
margin-left:-12px;
}
.page-1-1{background: #083846;}
.page-2-1{background: #9261BF;}
.page-2-2{background: #9261BF;}
.page-3-1{background: #F3533C;}
.page-3-2{ background-color:#F3533C;}
.page-4-1{ background-color:#FFBF50;}
.page-4-2{ background-color:#FFBF50;}
.page-5-1{ background-color:#083846;}
.page-1-1 .img_1{
height: auto;
width: 248px;
position: absolute;
top: 1%;
left: 50%;
margin-left: -124px;
}
.page-1-1 .img_2{
height: auto;
width: 185px;
position: absolute;
top:62%;
left: 50%;
margin-left: -92px;
}
.page-1-1 .img_2{
height: auto;
width: 185px;
position: absolute;
top:62%;
left: 50%;
margin-left: -92px;
}
.page-2-1 .img_1{
height: auto;
width: 158px;
position: absolute;
top: 2%;
left: 50%;
margin-left:-79px ;
z-index:2;
}
.page-2-1 .img_2{
height: auto;
width: 240px;
position: absolute;
top: 28%;
left: 50%;
margin-left:-120px ;
}
.page-2-1 .img_3{
height: auto;
width: 241px;
position: absolute;
top: 36%;
left: 50%;
margin-left:-120px ;
}
.page-2-1 .img_4{
height: auto;
width: 20px;
position: absolute;
top: 87%;
left: 50%;
margin-left:-10px ;
}
.page-2-1 .img_5{
height: auto;
width: 142px;
position: absolute;
top: 82%;
left: 50%;
margin-left:-71px ;
}
.page-2-1 .img_7{
height: auto;
width: 248px;
position: absolute;
top: 8%;
left: 50%;
margin-left:-124px ;
}
.page-2-2 .img_1 {
height:auto;
width:293px;
position:absolute;
left:50%;
top:5%;
margin-left:-146px;
}
.page-2-2 .img_2 {
height:auto;
width:260px;
position:absolute;
left:50%;
top:75%;
margin-left:-130px;
}
.page-2-2 .img_3 {
height:auto;
width:20px;
position:absolute;
left:50%;
top:87%;
margin-left:-10px;
}
.page-2-2 .img_6 {
height:auto;
width:25px;
position:absolute;
left:50%;
top:92%;
margin-left:-12px;
}
.page-3-1 .img_1 {
height:auto;width:166px;
position:absolute;
left:50%;
top:2%;
margin-left:-86px;
z-index:2;
}
.page-3-1 .img_2 {
height:auto;width:250px;
position:absolute;
left:50%;
top:30%;
margin-left:-125px;
}
.page-3-1 .img_3 {
height:auto;width:172px;
position:absolute;
left:50%;
top:28%;
margin-left:-55px;
}
.page-3-1 .img_4 {
height:auto;width:20px;
position:absolute;
left:50%;
top:87%;
margin-left:-10px;
}
.page-3-1 .img_5 {
height:auto;width:142px;
position:absolute;
left:50%;
top:82%;
margin-left:-71px;
}
.page-3-1 .img_6 {
height:auto;width:25px;
position:absolute;
left:50%;
top:92%;
margin-left:-12px;
}
.page-3-1 .img_7 {
height:auto;width:248px;
position:absolute;
left:50%;
top:43%;
margin-left:-124px;
}
.page-3-2 .img_1 {
height:auto;width:296px;
position:absolute;
left:50%;
top:5%;
margin-left:-148px;
}
.page-3-2 .img_2 {
height:auto;width:260px;
position:absolute;
left:50%;
top:75%;
margin-left:-130px;
}
.page-3-2 .img_3 {
height:auto;width:20px;
position:absolute;
left:50%;
top:87%;
margin-left:-10px;
}
.page-3-2 .img_6 {
height:auto;width:25px;
position:absolute;
left:50%;
top:92%;
margin-left:-12px;
}
.page-4-1 .img_1 {
height:auto;width:162px;
position:absolute;
left:50%;
top:2%;
margin-left:-84px;
z-index:2;
}
.page-4-1 .img_2 {
height:auto;width:230px;
position:absolute;
left:50%;
top:28%;
margin-left:-115px;
}
.page-4-1 .img_3 {
height:auto;width:161px;
position:absolute;
left:50%;
top:28%;
margin-left:-80px;
}
.page-4-1 .img_4 {
height:auto;width:20px;
position:absolute;
left:50%;
top:87%;
margin-left:-10px;
}
.page-4-1 .img_5 {
height:auto;width:142px;
position:absolute;
left:50%;
top:82%;
margin-left:-71px;
}
.page-4-1 .img_6 {
height:auto;width:25px;
position:absolute;
left:50%;
top:92%;
margin-left:-12px;
}
.page-4-1 .img_7 {
height:auto;width:271px;
position:absolute;
left:50%;
top:33%;
margin-left:-135px;
}
.page-4-1 .img_8 {
height:auto;width:169px;
position:absolute;
left:50%;
top:75%;
margin-left:-84px;
}
.page-4-2 .img_1 {
height:auto;width:298px;
position:absolute;
left:50%;
top:5%;
margin-left:-149px;
}
.page-4-2 .img_2 {
height:auto;width:260px;
position:absolute;
left:50%;
top:75%;
margin-left:-130px;
}
.page-4-2 .img_3 {
height:auto;width:20px;
position:absolute;
left:50%;
top:87%;
margin-left:-10px;
}
.page-4-2 .img_6 {
height:auto;width:25px;
position:absolute;
left:50%;
top:92%;
margin-left:-12px;
}
.page-5-1 .img_1 {
height:auto;width:280px;
position:absolute;
left:50%;
top:20%;
margin-left:-140px;
}
.page-5-1 .img_2 {
height:auto;
width:260px;
position:absolute;
left:50%;
top:67%;
margin-left:-130px;
}
animation.css
/*定义四个方向的动画*/
.pt-page-moveToLeft {
-webkit-animation: moveToLeft .6s ease both;
animation: moveToLeft .6s ease both;
}
.pt-page-moveFromLeft {
-webkit-animation: moveFromLeft .6s ease both;
animation: moveFromLeft .6s ease both;
}
.pt-page-moveToRight {
-webkit-animation: moveToRight .6s ease both;
animation: moveToRight .6s ease both;
}
.pt-page-moveFromRight {
-webkit-animation: moveFromRight .6s ease both;
animation: moveFromRight .6s ease both;
}
.pt-page-moveToTop {
-webkit-animation: moveToTop .6s ease both;
animation: moveToTop .6s ease both;
}
.pt-page-moveFromTop {
-webkit-animation: moveFromTop .6s ease both;
animation: moveFromTop .6s ease both;
}
.pt-page-moveToBottom {
-webkit-animation: moveToBottom .6s ease both;
animation: moveToBottom .6s ease both;
}
.pt-page-moveFromBottom {
-webkit-animation: moveFromBottom .6s ease both;
animation: moveFromBottom .6s ease both;
}
/*定义四个方向动画的实现过程*/
@-webkit-keyframes moveToLeft {
from { }
to { -webkit-transform: translateX(-100%); }
}
@keyframes moveToLeft {
from {}
to { -webkit-transform: translateX(-100%); transform: translateX(-100%); }
}
@-webkit-keyframes moveFromLeft {
from { -webkit-transform: translateX(-100%); }
}
@keyframes moveFromLeft {
from { -webkit-transform: translateX(-100%); transform: translateX(-100%); }
}
@-webkit-keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); }
}
@keyframes moveToRight {
from { }
to { -webkit-transform: translateX(100%); transform: translateX(100%); }
}
@-webkit-keyframes moveFromRight {
from { -webkit-transform: translateX(100%); }
}
@keyframes moveFromRight {
from { -webkit-transform: translateX(100%); transform: translateX(100%); }
}
@-webkit-keyframes moveToTop {
from { }
to { -webkit-transform: translateY(-100%); }
}
@keyframes moveToTop {
from { }
to { -webkit-transform: translateY(-100%); transform: translateY(-100%); }
}
@-webkit-keyframes moveFromTop {
from { -webkit-transform: translateY(-100%); }
}
@keyframes moveFromTop {
from { -webkit-transform: translateY(-100%); transform: translateY(-100%); }
}
@-webkit-keyframes moveToBottom {
from { }
to { -webkit-transform: translateY(100%); }
}
@keyframes moveToBottom {
from { }
to { -webkit-transform: translateY(100%); transform: translateY(100%); }
}
@-webkit-keyframes moveFromBottom {
from { -webkit-transform: translateY(100%); }
}
@keyframes moveFromBottom {
from { -webkit-transform: translateY(100%); transform: translateY(100%); }
}
/*iconUp*/
.pt-page-moveIconUp {
animation: moveIconUp ease 1.5s both infinite;
}
@keyframes moveIconUp {
0% { -webkit-transform: translateY(100%); transform: translateY(100%); opacity:0;}
50% { -webkit-transform: translateY(0%); transform: translateY(0%); opacity:1;}
100% { -webkit-transform: translateY(-100%); transform: translateY(-100%); opacity:0;}
}
/*moveCircle*/
.pt-page-moveCircle{
animation: moveCircle 1.2s ease-in-out;
}
@-webkit-keyframes moveCircle{
0%{transform: translateY(-80%);opacity: 0.1;}
5%{transform: translateY(-80%);opacity: 0.3;}
35%{transform: translateY(10%);opacity: 0.8;}
60%{transform: translateY(-30%);opacity: 0.8;}
65%{transform: translateY(-20%);opacity: 0.8;}
100%{transform: translateY(0%);opacity: 1;}
}
/*scaleUp*/
.pt-page-scaleUp{
animation:scaleUp 0.6s ease;
}
@-webkit-keyframes scaleUp{
from{transform: scale(0.4);}
to{}
}
/*flipInLeft*/
.pt-page-flipInLeft{
transform-origin: 50% 50%;
animation: flipInLeft .5s both ease-out;
}
@-webkit-keyframes flipInLeft{
from { -webkit-transform:rotateY(-90deg); opacity: 0.2; }
}
/*定义page-5-1*/
.pt-page-rotateCubeBottomIn{
animation:rotateCubeBottomIn .6s ease-in both ;
transform-origin: 50% 100%;
}
@keyframes rotateCubeBottomIn {
0%{transform: translateY(-100%) rotateX(90deg);opacity: 0.3}
50%{animation-timing-function: ease-out; transform: translateY(-50%) translateZ(-200px) rotateX(45deg);}
}
.pt-page-rotateCubeTopIn{
animation: rotateCubeTopIn 0.6s ease both;
transform-origin: 100% 50%;
}
@keyframes rotateCubeTopIn {
0%{translateY(100%) rotateX(-90deg);opacity: 0.3}
50%{animation-timing-function: ease-out;transform:translateY(50%) translateZ(-200px) rotateX(-45deg) ;}
}
index.js
/**
* Created by zhiyongYan on 2017/3/6.
*/
$(function () {
//初始化坐标变量
var last = {row:0,col:0};
var now = {row:1,col:1};
//初始化四个方向变量
var direction = {up:1,right:2,down:3,left:4};
//初始化是否移动变量
var isMoving = false;
//向上滑动
$(document).swipeUp(function () {
if(isMoving){
return;
}
//将滑动前手指作用的页面的坐标赋值给滑动之后上一个页面
last.row = now.row;
last.col = now.col;
//判断滑动的条件 滑动所需参数的设置
if(last.col!=5){
now.row = 1;
now.col = last.col + 1;
pageMove(direction.up);
}
});
//向下滑动
$(document).swipeDown(function () {
if(isMoving){
return;
}
//将滑动前手指作用的页面的坐标赋值给滑动之后上一个页面
last.row = now.row;
last.col = now.col;
//判断滑动的条件 滑动所需参数的设置
if(last.col!=1){
now.row = 1;
now.col = last.col - 1;
pageMove(direction.down);
}
});
//向左滑动
$(document).swipeLeft(function () {
if(isMoving){
return;
}
//将滑动前手指作用的页面的坐标赋值给滑动之后上一个页面
last.row = now.row;
last.col = now.col;
//判断滑动的条件 滑动所需参数的设置
if(last.col>1&&last.col<5&&last.row==1){
now.row = last.row + 1;
pageMove(direction.left);
}
});
//向右滑动
$(document).swipeRight(function () {
if(isMoving){
return;
}
//将滑动前手指作用的页面的坐标赋值给滑动之后上一个页面
last.row = now.row;
last.col = now.col;
//判断滑动的条件 滑动所需参数的设置
if(last.col>1&&last.col<5&&last.row==2){
now.row = last.row - 1;
pageMove(direction.right);
}
});
//定义move函数
function pageMove(dir) {
//初始化作用的两个页面
var lastPage = '.page-' + last.col + '-' + last.row;
var nowPage = '.page-' + now.col + '-' + now.row;
//初始化页面类
var outClass = '';
var inClass = '';
//匹配方向
switch (dir){
case direction.up:
outClass = 'pt-page-moveToTop';
inClass = 'pt-page-moveFromBottom';
break;
case direction.right:
outClass = 'pt-page-moveToRight';
inClass = 'pt-page-moveFromLeft';
break;
case direction.down:
outClass = 'pt-page-moveToBottom';
inClass = 'pt-page-moveFromTop';
break;
case direction.left:
outClass = 'pt-page-moveToLeft';
inClass = 'pt-page-moveFromRight';
break;
}
//为页面添加动画开始的类
$(nowPage).removeClass('hide');
$(lastPage).addClass(outClass);
$(nowPage).addClass(inClass);
isMoving = true;
//处理动画完成时页面的类
setTimeout(function () {
$(lastPage).addClass('hide');
$(lastPage).removeClass(outClass);
$(lastPage).removeClass('page-current');
$(lastPage).find('img').addClass('hide');
$(nowPage).addClass('page-current');
$(nowPage).removeClass(inClass);
$(nowPage).find('img').removeClass('hide');
isMoving = false;
},600);
}
});
touch.js
// Zepto.js
// (c) 2010-2016 Thomas Fuchs
// Zepto.js may be freely distributed under the MIT license.
;(function($){
var touch = {},
touchTimeout, tapTimeout, swipeTimeout, longTapTimeout,
longTapDelay = 750,
gesture
function swipeDirection(x1, x2, y1, y2) {
return Math.abs(x1 - x2) >=
Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down')
}
function longTap() {
longTapTimeout = null
if (touch.last) {
touch.el.trigger('longTap')
touch = {}
}
}
function cancelLongTap() {
if (longTapTimeout) clearTimeout(longTapTimeout)
longTapTimeout = null
}
function cancelAll() {
if (touchTimeout) clearTimeout(touchTimeout)
if (tapTimeout) clearTimeout(tapTimeout)
if (swipeTimeout) clearTimeout(swipeTimeout)
if (longTapTimeout) clearTimeout(longTapTimeout)
touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null
touch = {}
}
function isPrimaryTouch(event){
return (event.pointerType == 'touch' ||
event.pointerType == event.MSPOINTER_TYPE_TOUCH)
&& event.isPrimary
}
function isPointerEventType(e, type){
return (e.type == 'pointer'+type ||
e.type.toLowerCase() == 'mspointer'+type)
}
$(document).ready(function(){
var now, delta, deltaX = 0, deltaY = 0, firstTouch, _isPointerType
if ('MSGesture' in window) {
gesture = new MSGesture()
gesture.target = document.body
}
$(document)
.bind('MSGestureEnd', function(e){
var swipeDirectionFromVelocity =
e.velocityX > 1 ? 'Right' : e.velocityX < -1 ? 'Left' : e.velocityY > 1 ? 'Down' : e.velocityY < -1 ? 'Up' : null
if (swipeDirectionFromVelocity) {
touch.el.trigger('swipe')
touch.el.trigger('swipe'+ swipeDirectionFromVelocity)
}
})
.on('touchstart MSPointerDown pointerdown', function(e){
if((_isPointerType = isPointerEventType(e, 'down')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
if (e.touches && e.touches.length === 1 && touch.x2) {
// Clear out touch movement data if we have it sticking around
// This can occur if touchcancel doesn't fire due to preventDefault, etc.
touch.x2 = undefined
touch.y2 = undefined
}
now = Date.now()
delta = now - (touch.last || now)
touch.el = $('tagName' in firstTouch.target ?
firstTouch.target : firstTouch.target.parentNode)
touchTimeout && clearTimeout(touchTimeout)
touch.x1 = firstTouch.pageX
touch.y1 = firstTouch.pageY
if (delta > 0 && delta <= 250) touch.isDoubleTap = true
touch.last = now
longTapTimeout = setTimeout(longTap, longTapDelay)
// adds the current touch contact for IE gesture recognition
if (gesture && _isPointerType) gesture.addPointer(e.pointerId)
})
.on('touchmove MSPointerMove pointermove', function(e){
if((_isPointerType = isPointerEventType(e, 'move')) &&
!isPrimaryTouch(e)) return
firstTouch = _isPointerType ? e : e.touches[0]
cancelLongTap()
touch.x2 = firstTouch.pageX
touch.y2 = firstTouch.pageY
deltaX += Math.abs(touch.x1 - touch.x2)
deltaY += Math.abs(touch.y1 - touch.y2)
})
.on('touchend MSPointerUp pointerup', function(e){
if((_isPointerType = isPointerEventType(e, 'up')) &&
!isPrimaryTouch(e)) return
cancelLongTap()
// swipe
if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) ||
(touch.y2 && Math.abs(touch.y1 - touch.y2) > 30))
swipeTimeout = setTimeout(function() {
if (touch.el){
touch.el.trigger('swipe')
touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)))
}
touch = {}
}, 0)
// normal tap
else if ('last' in touch)
// don't fire tap when delta position changed by more than 30 pixels,
// for instance when moving to a point and back to origin
if (deltaX < 30 && deltaY < 30) {
// delay by one tick so we can cancel the 'tap' event if 'scroll' fires
// ('tap' fires before 'scroll')
tapTimeout = setTimeout(function() {
// trigger universal 'tap' with the option to cancelTouch()
// (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
var event = $.Event('tap')
event.cancelTouch = cancelAll
// [by paper] fix -> "TypeError: 'undefined' is not an object (evaluating 'touch.el.trigger'), when double tap
if (touch.el) touch.el.trigger(event)
// trigger double tap immediately
if (touch.isDoubleTap) {
if (touch.el) touch.el.trigger('doubleTap')
touch = {}
}
// trigger single tap after 250ms of inactivity
else {
touchTimeout = setTimeout(function(){
touchTimeout = null
if (touch.el) touch.el.trigger('singleTap')
touch = {}
}, 250)
}
}, 0)
} else {
touch = {}
}
deltaX = deltaY = 0
})
// when the browser window loses focus,
// for example when a modal dialog is shown,
// cancel all ongoing events
.on('touchcancel MSPointerCancel pointercancel', cancelAll)
// scrolling the window indicates intention of the user
// to scroll, not tap or swipe, so cancel all ongoing events
$(window).on('scroll', cancelAll)
})
;['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown',
'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
$.fn[eventName] = function(callback){ return this.on(eventName, callback) }
})
})(Zepto)