相关文章推荐

Touch 事件

TouchEvent 是一类描述手指在触摸平面(如触摸屏、触摸板等)的状态变化的事件。 TouchList 对象代表多个触点的一个列表。每个 Touch 对象代表一个触点,每个触点都由其位置、大小、形状、压力大小和目标 element 描述。

触摸事件类型

主要有以下几种:

  • touchstart - 当用户在触摸平面上放置了一个触点时触发
  • touchmove - 当用户在触摸平面上移动触点时触发
  • touchend - 当一个触点被用户从触摸平面上移除时触发
  • touchcancel - 当触点由于某些原因被中断时触发,如由于某个事件取消了触摸或触点个数超过了设备支持的个数
  • document.addEventListener('touchstart', touchEvent ,false);
    

    TouchList

    每个触摸事件被触发后,会生成一个 event 对象,event 对象里额外包括以下三个触摸列表:

  • touches - 包含了所有当前接触触摸平面的触点的 Touch 对象
  • targetTouches - 是包含了如下触点的 Touch 对象:触摸起始于当前事件的目标 element 上,并且仍然没有离开触摸平面的触点
  • changedTouches - 包含了代表所有从上一次触摸事件到此次事件过程中,状态发生了改变的触点的 Touch 对象
  • Touch

    这些列表里的每次触摸由 Touch 对象组成,Touch 对象里包含着触摸信息,主要属性如下:

    screenX: 511, screenY: 400, // 触点相对于屏幕左边沿的Y坐标 clientX: 244.37899780273438, clientY: 189.3820037841797, // 相对于可视区域 pageX: 244.37, pageY: 189.37, // 相对于 HTML 文档顶部,当页面有滚动的时候与 clientX=Y 不等 force: 1, // 压力大小,是从0.0(没有压力)到1.0(最大压力)的浮点数 identifier: 1036403715, // 一次触摸动作的唯一标识符 radiusX: 37.565673828125, // 能够包围用户和触摸平面的接触面的最小椭圆的水平轴(X轴)半径 radiusY: 37.565673828125, rotationAngle: 0, // 它是这样一个角度值:由 radiusX 和 radiusY 描述的正方向的椭圆,需要通过顺时针旋转这个角度值,才能最精确地覆盖住用户和触摸平面的接触面 target: {} // 此次触摸事件的目标 element

    查看以下 JSFiddle 示例:

    Touch 案例

    做一个移动端触摸点,仅限于屏幕窗口内移动,也可响应点击事件:

    var doc = document;
    var screenW = doc.body.clientWidth || screen.width;
    var screenH = doc.body.clientHeight || screen.height;
    var width = 48;
    var isMoved = false;
    var backToTop = doc.querySelector('.back-to-top');
    backToTop.addEventListener('touchstart', touchstart, false);
    backToTop.addEventListener('touchmove', touchmove, false);
    backToTop.addEventListener('touchend', touchend, false);
    function touchstart(ev) {
      isMoved = false;
    function touchmove(ev) {
      isMoved = true;
      var event = getEvent(ev);
      var coordinateX = event.changedTouches[0].clientX;
      var coordinateY = event.changedTouches[0].clientY;
      var left = parseFloat(coordinateX) - 20;
      var top = parseFloat(coordinateY) - 20;
      left = left <= 1.45 ? 1.45 : (left >= screenW - width ? screenW - width : left);
      top = top <= 1 ? 1 : (top >= screenH - width ? screenH - width : top);
      backToTop.style.left = left + 'px';
      backToTop.style.top = top + 'px';
      console.log('left: %f, top: %f', left, top);
    function touchend(ev) {
      !isMoved && alert('click');
    function getEvent(ev) {
      return ev ? ev : window.event;
    

    Drag 事件

    DragEvent 鼠标进行拖拽(drag)和释放(drop),一定要设置可拖拽目标,即设置属性 draggable="true"

    拖拽事件类型

  • 被拖动的源对象可以触发的事件:
  • dragstart - 源对象开始被拖动
  • drag - 源对象被拖动过程中(鼠标可能在移动也可能未移动)
  • dragend - 源对象被拖动结束
  • 拖动源对象到目标对象可以触发的事件:
  • dragenter - 源对象拖动进入目标对象时触发
  • dragover - 源对象拖动经过目标对象时触发
  • dragleave - 源对象拖动离开目标对象时触发
  • drop - 源对象放置于目标对象上时触发
  • dropEffect - 拖拽交互类型,通常决定浏览器如何显示鼠标光标并控制拖放操作.常见的取值有 copy、move、link、none
  • effectAllowed - 指定允许的交互类型,可以取值: copy、move、link、copyLink、copyMove、limkMove、all、none,默认为 uninitialized(允许所有操作)
  • files - 包含 File 对象的 FileList 对象,一般用于从本地向浏览器拖放文件.
  • types - 保存 DataTransfer 对象中设置的所有数据类型.
  • setData(format, data) - 以键值对设置数据,format 通常为数据格式,如 text、text/html
  • getData(format) - 获取设置的对应格式数据,format 与 setData()中一致
  • clearData(format) - 清除指定格式的数据
  • setDragImage(imgElement, x, y) - 设置自定义图标
  • draggableElement.addEventListener('dragstart', function (event) {
      event.dataTransfer.setData('text', 'Hello World');
    }, false);
    draggableElement.ondragstart = function(event) {
      event.dataTransfer.setData('text', 'Hello World');
    

    Drag 案例

    做一个 web 端触摸点,仅限于屏幕窗口内移动:

    var doc = document;
    var screenW = doc.body.clientWidth || screen.width;
    var screenH = doc.body.clientHeight || screen.height;
    var width = 48;
    var offsetX = 0;
    var offsetY = 0;
    var backToTop = doc.querySelector('.back-to-top');
    backToTop.addEventListener('dragstart', ondragstart, false);
    backToTop.addEventListener('drag', ondrag, false);
    backToTop.addEventListener('dragend', ondragend, false);
    function ondragstart(ev) {
      var event = getEvent(ev);
      offsetX = event.offsetX;
      offsetY = event.offsetY;
    function ondrag(ev) {
      var event = getEvent(ev);
      var coordinateX = event.clientX;
      var coordinateY = event.clientY;
      if (coordinateX === 0 && coordinateY === 0) {
        return; // 不处理拖动最后一刻X和Y都为0的情形
      coordinateX -= offsetX;
      coordinateY -= offsetY;
      coordinateX = coordinateX <= 0 ? 0 : (coordinateX >= screenW - width ? screenW - width : coordinateX);
      coordinateY = coordinateY <= 0 ? 0 : (coordinateY >= screenH - width ? screenH - width : coordinateY);
      backToTop.style.left = coordinateX + 'px';
      backToTop.style.top = coordinateY + 'px';
      console.log('left: %f, top: %f', coordinateX, coordinateY);
    function ondragend(ev) {
      console.log('drag end');
    

    做一个垃圾回收示例 JSFiddle:

    拖拽图片预览 JSFiddle:

    事件对象的位置

  • pageX = clientX + ScrollLeft(滚动条水平滚动距离)
  • pageY = clientY + ScrollTop(滚动条垂直滚动距离)
  • MDN - TouchEvent
  • 移动端 Touch 事件介绍 By kujian
  • js 中的 touch 事件及 gesture(手势)事件详解 — 第13.4.9节 By flyingpig2016
  • 原生拖拽,拖放事件(drag and drop) By qiu_deqing
  • HTML5 – 拖拽 API(含超经典例子) By 冯小东
  • 一张图轻松搞懂 javascript event 对象的 clientX、offsetX、screenX、pageX 区别 By ruoyiqing
  •  
    推荐文章