当前位置: 首页 > 工具软件 > Zepto.js > 使用案例 >

Zepto.js框架

太叔英锐
2023-12-01

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)
 类似资料: