1、触屏事件
	(1)触屏事件
	touch,代表一个触摸点,触摸点可以是手指,也可以是触摸笔。
	<body>
	  <style>
	   .nav {
	    width: 100px;
	    height: 100px;
	    background-color: red;
	   }
	  </style>
	<div class="nav"></div>
	<script>
	  var div = document.querySelector('div');
	  //1.手指触摸到某元素
	  div.addEventListener('touchstart',function() {
	    console.log('白龙网');
	  });
	  //2.手指在栽元素上移动
	  div.addEventListener('touchmove',function() {
	    console.log('drupal建站');
	  });
	  //3.手指离开某元素
	  div.addEventListener('touchend',function() {
	    console.log('SEO服务');
	  })
	</script>
	</body>
	(2)触屏事件对象
	白龙网认为,触屏事件对象是描述手指在触摸平面的状态变化的事件,用于描述一个或者多个触点,使用开发者可以检测触点的移动、增加、减少。
	<script>
	  var div = document.querySelector('div');
	  //1.手指触摸到某元素
	  div.addEventListener('touchstart',function(e) {
	    //1.触屏事件对象e.touches,触摸屏幕的手指列表
	    console.log(e.touches);
	    //2.触屏事件对象e.TargetTouches,触摸DOM元素的手指列表 ,常用
	    console.log(e.targetTouches);
	    console.log(e.targetTouches[0]);//第一个手指触摸DOM元素的信息,如坐标
	    //3.触屏事件对象changedTouches,手机状态发生了改变的列表,从无到有,从有到无
	    console.log(e.changedTouches);
	  });
	</script>
	(3)拖动DOM元素三步曲
	A.触摸元素touchStart:获取手指的初始坐标,同时获取盒子原来的位置;
	B.移动手指touchMove:获取手指滑动的坐标,计算手指的滑动距离,并且移动盒子;
	C.离开手指touchEnd:
	注意:手指移动会触发滚动屏幕,因此,这里需要阻止屏幕滚动e.preventDefault()。另外,手动元素的距离最终是要赋值给定位的top/left,因此拖动的元素必须有定位的功能。
	<body>
	  <style>
	   .nav {
	    position: absolute;
	    top: 0;
	    left: 0;
	    width: 100px;
	    height: 100px;
	    background-color: red;
	   }
	  </style>
	<div class="nav"></div>
	<script>
	 var div = document.querySelector('.nav');
	 var startX = 0;
	 var startY = 0;
	 var x = 0;
	 var y = 0;
	 div.addEventListener('touchstart',function(e) {
	  // 1.获取手指、盒子初始坐标
	  startX = e.targetTouches[0].pageY;
	  startY = e.targetTouches[0].pageY;
	  x = this.offsetLeft;
	  y = this.offsetTop;
	 });
	 div.addEventListener('touchmove',function(e) {
	  // 2.获取手指当前坐标,并计算出手指移动距离
	  var moveX = e.targetTouches[0].pageX -startX;
	  var moveY = e.targetTouches[0].pageY -startY;
	  // 3.盒子移动距离=手指移动距离+盒子初始偏移量
	  this.style.left = x + moveX + 'px';
	  this.style.top = y + moveY + 'px';
	  // 4.阻止屏幕滚动
	  e.preventDefault();
	 })
	</script>
	</body>
2、常见特效
	(1)移动轮播图
	<body>
	  <style>
	    .banner {position: relative;
	      width: 100%;
	      height: 200px;
	      overflow: hidden;/*设置超出隐藏,解决float产生的瓿 */
	    }
	    .banner ul {
	      width: 500%;
	      margin-left: -375px;
	      overflow: hidden;/*设置超出隐藏,解决float产生的瓿 */
	    }
	    .banner ul li {
	      float: left;
	      width: 20%;
	      height: 200px;
	    }
	    img {
	      width: 100%;
	    }
	    .banner ol {
	      position: absolute;
	      bottom: 5px;
	      left: 45%;
	    }
	    .banner ol li {
	      float: left;
	      width: 8px;
	      height: 8px;
	      background-color:red;
	      border-radius: 2px;
	      margin-right: 10px;
	      /* 让小圆点有一个过渡的效果 */
	      transition: all 3s;
	    }
	    .banner ol li.current {
	      width: 18px;
	    }
	  </style>
	  <div class="banner">
	    <ul>
	      <li><img src="./image/slidepic3.jpg" alt=""></li>
	      <li><img src="./image/slidepic1.jpg" alt=""></li>
	      <li><img src="./image/slidepic2.jpg" alt=""></li>
	      <li><img src="./image/slidepic3.jpg" alt=""></li>
	      <li><img src="./image/slidepic1.jpg" alt=""></li>
	    </ul>
	    <ol>
	      <li class="current"></li>
	      <li></li>
	      <li></li>
	    </ol>
	  </div>
	<script>
	  var div = document.querySelector('.banner');
	  var ul = div.children[0];
	  var index = 0;
	  var divWidth = div.offsetWidth;
	  var ol = div.children[1];
	  var flag = false;
	  //1.使用计数器,让图片每隔2秒按照索引号*盒子宽度的距离移动一次,同时给移动添加一个过渡效果;
	  var timer = setInterval(function() {
	    index++;    
	    var transformx = -index * divWidth;
	    ul.style.transition = 'all .3s';
	    ul.style.transform = 'translateX(' + transformx + 'px)';
	  },2000);
	  //2.当图片循环到最后一张图片后,就会显示空白,无内容可显示;可借助transitionend事件来监测图片移动到哪一张了;当循环到最后一张后,就把索引号赋值为0;同时取消动画效果、让图片按照索引号*盒子宽度移动
	  ul.addEventListener('transitionend',function() {
	    if (index >= 3) {
	      index = 0;
	      ul.style.transition = 'none';
	      var transformx = -index * divWidth;
	      ul.style.transform = 'translateX(' + transformx + 'px)';
	    } else if (index < 0) {
	      index = 2;
	      ul.style.transition = 'none';
	      var transformx = -index * divWidth;
	      ul.style.transform = 'translateX(' + transformx + 'px)';
	    };
	    //3.让小圆点跟随图片移动;首先要把OL中的current类去掉;然后把再给当前LI添加一个current,其编程思想仍然是干掉其它,留下自己
	    ol.querySelector('.current').classList.remove('current');
	    ol.children[index].classList.add('current');
	  });
	  //4.手指触摸屏幕轮播效果
	  var startx = 0;
	  var movex = 0;
	  //4-1手指触摸的初始坐标
	  ul.addEventListener('touchstart',function(e) {
	    startx = e.targetTouches[0].pageX;
	    //手指触摸时,停止轮播
	    clearInterval(timer);
	  });
	  //4-2手指移动坐标
	  ul.addEventListener('touchmove',function(e) {
	    movex = e.targetTouches[0].pageX - startx;
	    var transformx = -index * divWidth + movex;
	    ul.style.transition = 'none';
	    ul.style.transform = 'translateX(' + transformx + 'px)';
	    flag = true;
	    e.preventDefault();
	  });
	  //4-3手动离开的效果
	  ul.addEventListener('touchend',function() {
	    //4-3-1如果移动距离大于50,就实现左右滑动图片的效果
	    if (flag) {//如果有移动距离,则判断并执行;反之,如果没有没有移动距离,则不做判断
	      if (Math.abs(movex) > 50) {
	      if (movex > 0) {
	        index--;
	      } else {
	        index++;
	      }
	      var transformx = -index * divWidth;
	      ul.style.transition = 'all 3s';
	      ul.style.transform = 'translateX(' + transformx + 'px)';
	    } else {
	      //4-3-2如果小于50,就回弹
	      var transformx = -index * divWidth;
	      ul.style.transform = 'translateX(' + transformx + 'px)';
	    };
	    }
	    //4-4判断条件结束后,要先清除之前的定时器,再开启定时器
	    clearInterval(timer);
	    timer = setInterval(function() {
	    index++;    
	    var transformx = -index * divWidth;
	    ul.style.transition = 'all .3s';
	    ul.style.transform = 'translateX(' + transformx + 'px)';
	  },2000);
	  })
	</script>
	</body>
	(2)classlist类名操作
	返回的是元素的类列表,以伪数组的形式存储,因此,可以使用数组arr[i]来获取、添加、删除、切换类。使用classlist操作类,要注意引号内只留类名即可,不要加点“.”。这一点与querySelector不同。
	<body>
	  <style>
	   .bg {
	    background-color: #000;
	   } 
	  </style>
	<button class="one">开关</button>
	<script>
	var button = document.querySelector('button');
	//1.获取元素的类
	console.log(button.classList);
	//2.给元素追加一个类
	button.classList.add('two');
	//3.删除元素的一个类
	button.classList.remove('one');
	//4.切换类:点击时添加一个类,再点击删除一个类,从而实现了类的切换
	button.addEventListener('click',function() {
	  document.body.classList.toggle('bg');
	})
	</script>
	</body>
	(3)返回顶部模块操作
	PC端的一些网页特效,在移动端照样可用。
	<body>
	  <style>
	    .content {
	      position: relative;
	    }
	    .goback {
	      position: fixed;
	      top: 200px;
	      right: 0;
	      width: 30px;
	      height: 30px;
	      background-color: #999;
	      text-align: center;
	      line-height: 30px;
	      border-radius: 50%;
	      display: none;
	    }
	    .tops {
	      height: 400px;
	      width: 100%;
	      background-color: red;
	    }
	    .middle {
	      height: 1500px;
	      width: 100%;
	      background-color: orange;
	    }
	    .bottoms {
	      height: 1500px;
	      width: 100%;
	      background-color: blue;
	    }
	  </style>
	<div class="cnetent">
	  <div class="goback">返</div>
	    <div class="tops">top</div>
	    <div class="middle">middle</div>
	    <div class="bottoms">bottom</div>
	</div>
	<script>
	 var goback = document.querySelector('.goback');
	 var bottoms = document.querySelector('.bottoms');
	 window.addEventListener('scroll',function() {
	  if(window.pageYOffset >= bottoms.offsetTop) {
	    console.log(bottoms.offsetTop);
	    goback.style.display = 'block';
	  } else {
	    goback.style.display = 'none';
	  }
	 });
	 window.addEventListener('click',function() {
	  window.scroll(0,0);
	 })
	</script>
	</body>
3、开发插件
	(1)fastclick.js插件
	移动端点击有一个300ms的延时,解决的办法是禁用页面缩放:
	<meta name="viewport" content="user-scalable=no">
	或者使用touch封装函数解决。
	最简单的方法是使用fastclick.js插件直接解决这个延迟。具体方法是,先引入JS文件,再按照其语法规范使用即可。下载地址为:https://github.com/ftlabs/fastclick/tree/main/lib
	(2)swiper
	swiper插件的使用,分为三步,一是到到swiper官网下载swiper源文件;二是解压swiper源文件,到dist文件中找到CSS/JS,并引入CSS/JS;三是通过查看源码的方式进入源码,复制html+CSS+JS到自己开发文档。即可使用已存在的轮播效果。
	另外,在swiper3里有“在线演示->基础演示”的案例,对应源码中的deom文件夹,即页面中的效果,根据编号,在对应的demo文件中可以找到。
	(3)superside插件
	superside基于JQ开发,因此要根据使用说明先引入相关插件,再使用HTML/JS/CSS。同时要注意的是,这个插件有PC/移动两种形式,可有选择性的下载源码包使用。
	(4)isscroll插件
	来自https://github.com/cubiq/iscroll的一个插件,可以下载下来体验
	(5)zy-media视频插件
	这个移动端的视频插件,可以到https://github.com/ireaderlab/zyMedia下载。以后需要什么插件都可以在github上查找下载。
4、开发框架
	框架大而全,一一套解决方案。
	插件,小而简单。功能单一。
	(1)bootstrap
	熟悉每个功能的用法。
	下载源码后,引入bottstrap的CSS/JS,但是引入bootstrap的js之前,先引入JQ,因为bootstrap依赖于jq。
5、本地存储
	(1)特征
	①数据存储在浏览器中;
	②读取、设置方便,甚至刷新都不会丢失;
	③容易大,sessionStroage可存5M,localStorage可存储20M;
	④只有存储字符串,可以将对象JSON.String()编码后存储。
	(2)分类
	①window.sessionStorage
	A.生命周期是关闭浏览器容器;
	B.在同一个窗口下数据可以共享;
	C.以键值对的形式存储使用;
	<body>
	 <input type="text" name="" id=""> 
	 <button class="set">存储数据</button>
	 <button class="get">获取数据</button>
	 <button class="remove">删除数据</button>
	 <button class="del">清空所有数据</button>
	<script>
	var ipt = document.querySelector('input');
	var set = document.querySelector('.set');
	var get = document.querySelector('.get');
	var remove = document.querySelector('.remove');
	var clear = document.querySelector('.del');
	set.addEventListener('click',function() {
	  //1.存储数据,即增加数据;增加第二个数据时,会覆盖第一个数据,即修改
	  var val = ipt.value;
	  sessionStorage.setItem('uname',val);
	});
	get.addEventListener('click',function() {
	  //2.获取数据,即查询数据
	  console.log(sessionStorage.getItem('uname'));
	});
	remove.addEventListener('click',function() {
	  //3.删除数据
	  sessionStorage.removeItem('uname');
	});
	clear.addEventListener('click',function() {
	  //4.清空所有数据
	  sessionStorage.clear();
	})
	</script>
	</body>
	②window.localStorage
	A.生命周期永久生效,除非手动删除;
	B.多窗口同一浏览器可以共享数据;
	C.以键值对的形式在座数据。
	<body>
	 <input type="text" name="" id=""> 
	 <button class="set">存储数据</button>
	 <button class="get">获取数据</button>
	 <button class="remove">删除数据</button>
	 <button class="del">清空所有数据</button>
	<script>
	var ipt = document.querySelector('input');
	var set = document.querySelector('.set');
	var get = document.querySelector('.get');
	var remove = document.querySelector('.remove');
	var clear = document.querySelector('.del');
	set.addEventListener('click',function() {
	  var val = ipt.value;
	  localStorage.setItem('uname',val);
	});
	get.addEventListener('click',function() {
	  alert(localStorage.getItem('uname'))
	});
	remove.addEventListener('click',function() {
	  localStorage.removeItem('uname');
	});
	clear.addEventListener('click',function() {
	  localStorage.clear();
	})
	</script>
	</body>
	③案例:记住用户和密码
	<body>
	  <input type="text" name="" id="uname">
	  <input type="checkbox" name="" id="remember">
	  记住用户名
	<script>
	var uname = document.querySelector('#uname');
	var remember = document.querySelector('#remember');
	if (localStorage.getItem('uname')) {
	  uname.value = localStorage.getItem('uname');
	  remember.checked = true;
	}
	//监测单选框状态是否变化,这里用到了change事件
	remember.addEventListener('change',function(){
	  if(this.checked) {
	    localStorage.setItem('uname',uname.value);
	  } else {
	    localStorage.removeItem('uname');
	  }
	})
	</script>
	</body>