移动端触屏事件

770 阅读3分钟

常见的触屏touch事件

  • touchstart 手指触摸到一个DOM元素时触发
  • touchmove 手指在一个DOM元素上滑动时触发
  • touchend 手指从一个DOM元素上移开时触发

触摸事件对象(TouchEvent)

是一个描述手指在触摸平面的状态变化的事件,这类事件用于描述一个或多个触摸点,使开发者可以检测触点的移动,触点的增加和减少。 touchstart,touchmove,touchend三个事件都有各自的事件对象

三个常见的对象

  • touches 正在触摸屏幕的所有手指的一个列表
  • targetTouches 正在触摸当前DOM元素上的手指的一个列表 【重点】
  • changedTouches 手指状态发生了改变的列表,从无到有,从右到无的变化

移动端拖动元素

touchstart,touchmove,touchend可以实现拖动元素

但是拖动元素需要当前手指的坐标值,我们可以使用targetTouches[0]里面pageX和pageY

移动端拖动的原理:手指移动中,计算出手指移动的距离,然后用盒子原来的位置+手指移动的距离

手指移动的距离:手指滑动中的位置 减去 手指刚开始触摸的位置

拖动元素三步骤:

  • 触摸元素touchstart,获取手指初始坐标,同时 获得盒子原来的位置
  • 移动手指 touchmove 计算手指的滑动距离,并且移动盒子
  • 离开手指 touchend

注意:* **手指移动也会触发滚动屏幕所以这里要阻止默认的屏幕滚动 e.preventDefault() ***

classList属性

classList属性是HTML5新增的一个属性,返回元素的类名,但是ie10以上版本支持

该属性用于在元素中添加,移除以及切换css类

注意:一下方法里面,所有类名都不带点

添加类

element.classList.add('类名')

移除类

element.classList.remove('类名')

切换类

element.classList.toggle('类名')

移动端轮播图

/* 
1.自动播放功能
2.开启定时器
3.移动端移动.使用translate移动
4.想要图片优雅的移动,添加过渡效果
*/

// 1 获取元素
var focus = document.querySelector('.focus')
var ulEle = focus.children[0]
var olEle = focus.children[1]
// 2 获取focus的宽度
var w = focus.offsetWidth
// console.log(w, 'w')
//  3利用定时器 自动轮播图片
var index = 0
var timer = setInterval(function () {
  index++
  // console.log(index, '00')
  var translatex = -index * w
  // console.log(index, translatex)
  ulEle.style.transition = 'all .3s'
  ulEle.style.transform = 'translateX(' + translatex + 'px)'
}, 2000)
/* 
1.自动播放功能 无缝滚动
我们判断要等到图片滚动完毕再去判断,就是过渡完成后判断
此时需要添加检测过渡完成事件 transitionend
判断条件:如果索引号等于3  说明是最后一张图片,此时索引号要复原 0
此时图片,去掉过渡效果 ,然后移动
如果索引号小于0 说明是倒着走  
此时图片,去掉过渡效果 ,然后移动
*/
ulEle.addEventListener('transitionend', function () {
  console.log('完成', index)
  if (index >= 3) {
    index = 0
    // 去掉过渡效果让我们的ulEle 快速的跳到目标位置
    ulEle.style.transition = 'none'
    // 利用最新的索引号乘以宽度  移动图片
    var translatex = -index * w
    // console.log(index, translatex)
    ulEle.style.transform = 'translateX(' + translatex + 'px)'
  } else if (index < 0) {
    index = 2
    ulEle.style.transition = 'none'
    var translatex = -index * w
    // console.log(index, translatex)
    ulEle.style.transform = 'translateX(' + translatex + 'px)'
  }

  /* 
    小圆点跟随变化效果
    把OL里面带有current类名选出来 去掉类名
    让当前索引号的小li  加上current 
    过渡结束之后变化,小圆点变化要写道transitionend事件里面
    
    */
  // 把OL里面带有current类名选出来 去掉类名
  // console.log(olEle, index)
  olEle.querySelector('.current').classList.remove('current')
  // 让当前索引号的小li  加上current
  olEle.children[index].classList.add('current')
})

/* 
手指滑动轮播图
本质就是ul跟随手指移动,就是移动端拖动元素
触摸元素 touchstart  获取手指初始坐标
移动手指  touchmove 计算手指的滑动距离 并且移动盒子
离开手指 touchend 根据滑动距离分不同情况
如果移动距离小于某个像素  就回弹原来的位置
如果移动距离大于某个像素  就上一张下一张滑动
滑动分左滑动和右滑动 判断标准是移动距离正负 负值就是左滑  反之右滑
左滑就播放下一张  index++
右滑 就播放上一张 index--
*/

// 获取手指初始坐标
var startX = 0
var moveX = 0
ulEle.addEventListener('touchstart', function (e) {
  startX = e.targetTouches[0].pageX
  // 停止定时器
  clearInterval(timer)
})

// 移动手指  touchmove 计算手指的滑动距离 移动盒子
ulEle.addEventListener('touchmove', function (e) {
  moveX = e.targetTouches[0].pageX - startX
  // 移动盒子  盒子原来的位置 + 手指移动的距离
  var translatex = -index * w + moveX

  // 手指拖动时 动画效果要取消 过渡
  ulEle.style.transition = 'none'
  ulEle.style.transform = 'translateX(' + translatex + 'px)'
  e.preventDefault() //阻止滚动屏幕的行为
})

// 手指离开  根据移动距离 去判断是回弹还是播放上一张 下一张
ulEle.addEventListener('touchend', function (e) {
  // console.log('touchend', moveX)
  if (Math.abs(moveX) > 50) {
    // 如果是右滑 就是播放上一张 moveX 是正值
    if (moveX > 0) {
      index--
    } else {
      // 左滑 就是播放下一张 moveX是正值
      index++
    }
    var translatex = -index * w
    ulEle.style.transition = 'all .3s'
    ulEle.style.transform = 'translateX(' + translatex + 'px)'
  } else {
    // 移动距离小于50px我们就回弹
    var translatex = -index * w
    ulEle.style.transition = 'all .1s'
    ulEle.style.transform = 'translateX(' + translatex + 'px)'
  }

  // 手指离开时 重新开启定时器
  clearInterval(timer)
  timer = setInterval(function () {
    index++
    // console.log(index, '00')
    var translatex = -index * w
    // console.log(index, translatex)
    ulEle.style.transition = 'all .3s'
    ulEle.style.transform = 'translateX(' + translatex + 'px)'
  }, 2000)
})