前端JS H5 touch事件封装,更加高效的开发移动端 - 戴向天

  1. 云栖社区>
  2. 博客>
  3. 正文

前端JS H5 touch事件封装,更加高效的开发移动端 - 戴向天

幸运券发放 2019-07-05 10:50:04 浏览409
展开阅读全文

前端JS H5 touch事件封装,更加高效的开发移动端 - 戴向天
大家好!我叫戴向天。今天我给大家分享一个我自己封装的H5 touch事件的封装。

该方法的使用特别的简单,废话不多说。先上代码 ↓↓↓↓↓

/* 给元素绑定事件 /

  function touch({dom, start, move, end, stop = true, change}) {
    const f = {
      data: {},
      start(e) {                        //手指触碰的屏幕就会触发(一次)
        stop && e.preventDefault()        //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
        f.data = {                        //储存的是一些数据
          ...f.data,                    //扩展运算,将之前的数据进行合并
          x: e.touches[0].pageX,        //手指开始的横向位置
          y: e.touches[0].pageY,        //手指开始的纵向位置
          ex: 0,                        //手指结束的横向位置
          ey: 0,                        //手指结束的纵向位置
          time: new Date().getTime(),    //手指的开始时间
        }
        start && start(f.data)        //执行自定义的 start 方法
      },
      move(e) {                    //多次
        stop && e.preventDefault()        //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
        f.data = {                //储存的是一些数据
          ...f.data,            //扩展运算,将之前的数据进行合并
          ex: e.touches[0].pageX,            //手指结束的横向位置
          ey: e.touches[0].pageY,            //手指结束的纵向位置
        }
        move && move({                    //执行自定义的 move方法,并且把得到的数据进行返回
          x: e.touches[0].pageX,
          y: e.touches[0].pageY,
          dx: f.data.ex - f.data.x,
          dy: f.data.ey - f.data.y
        })
      },
      end(e) {                //手指离开屏幕就会触发(一次)
        stop && e.preventDefault()        //阻止冒泡,当stop为false的时候就运行冒泡,默认为true
        let time = new Date().getTime()    //手指离开的时间
        end && end({                //执行自定义的 end 方法,并且把得到的数据进行返回
          time,                    //当前时间
          startTime: f.data.time,        //手指的开始时间
          dt: time - f.data.time,            //手指在屏幕逗留的时间差 ms
          dy: (f.data.ey || f.data.y) - f.data.y,        //手指在屏幕上的纵向的移动距离
          dx: (f.data.ex || f.data.x) - f.data.x        //手指在屏幕上的横向的移动距离
        })
        
        // ↓ 下面的就是执行判断手指移动的方向,当达到条件,就会执行change事件,
        // change 返回的参数 
        //      direction: left | right | up | down | origin
        if (new Date().getTime() - f.data.time < 300) {        // 手指开屏幕上的时间很短

          if (Math.abs(f.data.ex - f.data.x) > 20 && Math.abs(f.data.ex - f.data.x) > Math.abs(f.data.ey - f.data.y)) {
            if (change) {
              if (f.data.ex > f.data.x) {
                change({
                  direction: 'right'
                })
              } else if (f.data.ex < f.data.x) {
                change({
                  direction: 'left'
                })
              }
            }
          } else if (Math.abs(f.data.ey - f.data.y) > 20 && Math.abs(f.data.ex - f.data.x) < Math.abs(f.data.ey - f.data.y)) {
            if (change) {
              if (f.data.ey > f.data.y) {
                change({
                  direction: 'down'
                })
              } else if (f.data.ey < f.data.y) {
                change({
                  direction: 'up'
                })
              }
            }
          } else {
            change && change({
              direction: 'origin'
            })
          }
        } else if (Math.abs(f.data.ey - f.data.y) >= 50) {
          if (change) {
            if (f.data.ey > f.data.y) {
              change({
                direction: 'down'
              })
            } else if (f.data.ey < f.data.y) {
              change({
                direction: 'up'
              })
            }
          }
        } else if (Math.abs(f.data.ex - f.data.x) >= 50) {
          if (change) {
            if (f.data.ex > f.data.x) {
              change({
                direction: 'right'
              })
            } else if (f.data.ex < f.data.x) {
              change({
                direction: 'left'
              })
            }
          }
        } else {
          change && change({
            direction: 'origin'
          })
        }
      }
    }
    // 这里是防止dom元素绑定事件异常,导致整体页面无法正常往下执行
    try {
      dom.removeEventListener('touchstart', f.start)
      dom.addEventListener('touchstart', f.start)
      dom.removeEventListener('touchmove', f.move)
      dom.addEventListener('touchmove', f.move)
      dom.removeEventListener('touchend', f.end)
      dom.addEventListener('touchend', f.end)
    } catch (e) {
      console.error('给dom元素绑定事件的时候出现了错误', e)
    }
  }

下面我写了一个案例的vue文件 按钮组的组件

里面的style代码是我在我写的公共样式里面进行提取出来的。

dd-img组件其实就是一个图片自适应的组件。 该组件内类容在上篇文章有过描述


   v-if="config.buttons.length>0">
<div class="flex" ref="ddBanner" style="transform: translateX(0px);"
     :style="{'width':7.5 * getBtsGroup(config.buttons).length + 'rem'}">
  <div v-for="(buttonList,chunkBtnKey) in getBtsGroup(config.buttons)" :key="chunkBtnKey">
    <ul class="flex-wrap flex w-750" :class="config.className">
      <li class="w20 t-c pad-b-10"
          v-for="(item,key) in buttonList"
          :key="key"
          :class="item.parentClass"
          @click.stop="handle(item)"
      >
        <div
          :class="item.class"
          :style="item.style"
        >
          <dd-img v-if="item.src" class="mar-a mar-b-10" :src="item.src" :width="0.85" :height="0.85"/>
          <i v-if="item.icon" class="iconfont" :class="item.icon"></i>
          <div v-else class="bg-e-i hei100"></div>
        </div>
        <h3 :class="{'col-t':item.active}">{{item.name}}</h3>
      </li>
    </ul>
  </div>
</div>


export default {

props: {
  config: {
    type: Object,
    default: Object
  },
  deliver: {
    type: Boolean,
    default: false,
  },
},
data () {
  return {
    width: 0,
    len: 0,
    key: 0,
    touchData: {
      index: 0,
    },
  }
},
methods: {
  getBtsGroup (bts) {
    let group = [],
      itemGroup = []
    bts.forEach((item, i) => {
      if (i % 10) {
        itemGroup.push(item)
      } else {
        itemGroup = []
        itemGroup.push(item)
        group.push(itemGroup)
      }
    })
    return group
  },
  handle (item) {
    console.log(item)
  }
},
created () {
  const that = this
  that.len = that.getBtsGroup(that.config.buttons).length
  that.len > 1 && setTimeout(() => {
    const ddBanner = that.$refs.ddBanner
    that.width = that.len * that.$refs.ddBanner.clientWidth
    ddBanner.style.width = that.width + 'px'
    this.touch({
      dom: ddBanner,
      start ({x, y, time}) {
        that.touchData.x = x
        that.touchData.y = y
        that.touchData.time = time
        let tf = ddBanner.style.transform
        that.touchData.tf = Number(tf.split('(')[1].split('px')[0])
      },
      move ({x, y}) {
        that.touchData.ex = x
        that.touchData.ey = y
        ddBanner.style.transitionDuration = '0ms'
        ddBanner.style.transform = `translateX(${that.touchData.ex - that.touchData.x + that.touchData.tf}px)`
      },
      change ({direction}) {
        switch (direction) {
          case 'left':
            that.touchData.index > -(that.len - 1) && that.touchData.index--
            break
          case 'right':
            Math.abs(that.touchData.index) > 0 && that.touchData.index++
            break
          case 'up':
            break
          case 'down':
            break
          case 'origin':
            break
        }
        that.key = Math.abs(that.touchData.index)
        ddBanner.style.transitionDuration = `500ms`
        ddBanner.style.transform = `translateX(${ddBanner.parentNode.clientWidth * that.touchData.index}px)`
      }
    })
  }, 10)
}

}


.fon-b {
font-size: 28px;
}

.pad-t {
padding-top: 30px;
}
.pad-b-10 {
padding-bottom: 10px;
}
.over-h {
overflow: hidden;
}
.flex-wrap {
flex-wrap: wrap;
}
.flex {
display: flex;
}
.w-750 {
width: 750px;
}
.w20 {
width: 20%;
}
.t-c {
text-align: center;
}
.pad-b-10 {
padding-bottom: 10px;
}
.mar-a {
margin: 0 auto;
}
.mar-b-10 {
margin-bottom: 10px;
}
.bg-e-i {
background-color: #eee !important;
}

该组件的使用方法

export default{

data(){
    return {
         buttonGroupConfig: {
              buttons: [
                {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }, {
                  src: 'https://img.52z.com/upload/news/image/20180823/20180823122912_66977.jpg',
                  name: '女生'
                }
              ],
            },
    }
}

}

由于不知道怎么上传屏幕录制并生成GIF图。具体的效果没能展示。

作者:戴向天
来源:CSDN
原文:https://blog.csdn.net/weixin_41088946/article/details/90764437
版权声明:本文为博主原创文章,转载请附上博文链接!

网友评论

作者关闭了评论