touch事件的简单封装

在Q群有很多人在问touch事件怎么去监控它的左右滑动,于是乎有时间我就萌生了封装touch对象的想法。
利用ES6的新特性class写的touch类,下面来详情介绍一下我的思路:利用ES6的新特性class写的touch类,下面来详情介绍一下我的思路:
下面这个object存放的是用于判断事件的各种参数,它在touchstart、touchmove、touchend的过程中绑定相关数据达到最终的判断结果,具体将过程在后面介绍。
this.obj = {
  x1: 0,  // 初始横坐标
  y1: 0,  // 初始纵坐标
  timeStart: 0, // 初始时间戳
  x2: 0,  // 结束横坐标
  y2: 0,  // 结束纵坐标
  timeEnd: 0, // 结束时间戳
  x: 50,  // 横坐标的容错值
  y: 50,  // 纵坐标的容错值
  interval: 200,  // 有效时间间隔
  sX: 0, // 存放横坐标差
  sY: 0, // 存放纵坐标差
  sTime: 0,  // 存放touch事件的时间长度
  getXandYandTime: function () { // 获取坐标差,和touch时间的长度
    this.sX = this.x2 - this.x1
    this.sY = this.y2 - this.y1
    this.sTime = this.timeEnd - this.timeStart
  },
  len: 0 // 记录多少个触摸点
}

下面的object是一个事件委托的列表,每一种事件都用一个列表来存放,避免多次绑定造成的覆盖影响。
this.event = {
  touch: [],
  longTouch: [],
  leftMove: [],
  rightMove: [],
  topMove: [],
  bottomMove: []
}

下面是核心代码,touch事件的判断逻辑。touchstart记录初始坐标值,touchmove跟踪最终坐标点,在touchend或touchcancel根据sX、sY、sTime等参数来判断是什么事件。
init() {
  this.elm.addEventListener('touchstart', event => {
    // 保证是单指点击事件
    this.obj.len = event.touches.length
    if (this.obj.len === 1) {
      this.obj.x1 = this.obj.x2 = event.touches[0].pageX
      this.obj.y1 = this.obj.y2 = event.touches[0].pageY
      this.obj.timeStart = new Date().getTime()
    }
  })
  this.elm.addEventListener('touchmove', (event) => {
    if (this.obj.len === 1){
      this.obj.x2 = event.touches[0].pageX
      this.obj.y2 = event.touches[0].pageY
    }
  })
  var touchend = (event) => {
    if (this.obj.len != 1) {
      return
    }
    let str = ''
    this.obj.timeEnd = new Date().getTime()
    this.obj.getXandYandTime()
    // 判断是否为点击事件
    if (Math.abs(this.obj.sX) < this.obj.x
      && Math.abs(this.obj.sY) < this.obj.y){
      if (this.obj.sTime < this.obj.interval) {
        // console.log('点击事件')
        str = 'touch'
      }
      else {
        // console.log('长按事件')
        str = 'longTouch'
      }
    }
    else {
      if (Math.abs(this.obj.sX) > Math.abs(this.obj.sY)) {
        if (this.obj.sX > 0) {
          // console.log('右滑事件')
          str = 'rightMove'
        } else {
          // console.log('左滑事件')
          str = 'leftMove'
        }
      }
      else {
        if (this.obj.sY > 0) {
          // console.log('下滑事件')
          str = 'bottomMove'
        } else {
          // console.log('上滑事件')
          str = 'topMove'
        }
      }
    }
    this.mapEvent(str, event)
  }
  this.elm.addEventListener('touchend', (event) => {
    touchend.call(this, event)
  })
  this.elm.addEventListener('touchcancel', (event) => {
    touchend.call(this, event)
  })

}

上面介绍了自定义touch事件的判断,接下来看看事件的绑定和解绑,从下面三个方法可以看出来,on将要绑定的事件委托压入数组,off将为委托清空,执行的时候讲列表的函数都执行一次,默认传入event参数。
// 绑定自定义事件
on(str, fn) {
  this.event[str].push(fn)
  return this
}
// 解绑自定义事件
off(str) {
  this.event[str] = []
  return this
}
// 执行自定义事件
mapEvent(str, event) {
  for(let val of this.event[str]){
    val(event)
  }
}

最后附上全部的代码:
class touch {
  constructor(elm) {
    this.elm = elm
    this.obj = {
      x1: 0,  // 初始横坐标
      y1: 0,  // 初始纵坐标
      timeStart: 0, // 初始时间戳
      x2: 0,  // 结束横坐标
      y2: 0,  // 结束纵坐标
      timeEnd: 0, // 结束时间戳
      x: 50,  // 横坐标的容错值
      y: 50,  // 纵坐标的容错值
      interval: 200,  // 有效时间间隔
      sX: 0, // 存放横坐标差
      sY: 0, // 存放纵坐标差
      sTime: 0,  // 存放touch事件的时间长度
      getXandYandTime: function () {
        console.log(this)
        this.sX = this.x2 - this.x1
        this.sY = this.y2 - this.y1
        this.sTime = this.timeEnd - this.timeStart
      },
      len: 0 // 记录多少个触摸点
    }
    // 事件代理列表
    this.event = {
      touch: [],
      longTouch: [],
      leftMove: [],
      rightMove: [],
      topMove: [],
      bottomMove: []
    }
    this.init()
  }
  // 初始化绑定touchstarttouchmovetouchend事件,用于判断用户执行的操作
  init() {
    this.elm.addEventListener('touchstart', event => {
      // 保证是单指点击事件
      this.obj.len = event.touches.length
      if (this.obj.len === 1) {
        this.obj.x1 = this.obj.x2 = event.touches[0].pageX
        this.obj.y1 = this.obj.y2 = event.touches[0].pageY
        this.obj.timeStart = new Date().getTime()
      }
    })
    this.elm.addEventListener('touchmove', (event) => {
      if (this.obj.len === 1){
        this.obj.x2 = event.touches[0].pageX
        this.obj.y2 = event.touches[0].pageY
      }
    })
    var touchend = (event) => {
      if (this.obj.len != 1) {
        return
      }
      let str = ''
      this.obj.timeEnd = new Date().getTime()
      this.obj.getXandYandTime()
      // 判断是否为点击事件
      if (Math.abs(this.obj.sX) < this.obj.x
        && Math.abs(this.obj.sY) < this.obj.y){
        if (this.obj.sTime < this.obj.interval) {
          // console.log('点击事件')
          str = 'touch'
        }
        else {
          // console.log('长按事件')
          str = 'longTouch'
        }
      }
      else {
        if (Math.abs(this.obj.sX) > Math.abs(this.obj.sY)) {
          if (this.obj.sX > 0) {
            // console.log('右滑事件')
            str = 'rightMove'
          } else {
            // console.log('左滑事件')
            str = 'leftMove'
          }
        }
        else {
          if (this.obj.sY > 0) {
            // console.log('下滑事件')
            str = 'bottomMove'
          } else {
            // console.log('上滑事件')
            str = 'topMove'
          }
        }
      }
      this.mapEvent(str, event)
    }
    this.elm.addEventListener('touchend', (event) => {
      touchend.call(this, event)
    })
    this.elm.addEventListener('touchcancel', (event) => {
      touchend.call(this, event)
    })

  }
  // 绑定自定义事件
  on(str, fn) {
    this.event[str].push(fn)
    return this
  }
  // 解绑自定义事件
  off(str) {
    this.event[str] = []
    return this
  }
  // 执行自定义事件
  mapEvent(str, event) {
    for(let val of this.event[str]){
      val(event)
    }
  }
}

调用方式:
var t = new touch(document.getElementsByClassName('test')[0]).on('touch', event => {
  console.log('touch')
}).on('leftMove', event => {
  console.log('leftMove')
}).off('touch')

你可能感兴趣的:(javascript)