JavaScript之BOM(三):移动端网页特效之触屏事件、对象、插件和框架

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>