javascript 在触摸屏上拖放

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11817750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 14:26:46  来源:igfitidea点击:

drag-and-drop on touchscreen

javascriptdrag-and-droptouch

提问by Niet the Dark Absol

I've been searching for a clear guide on how these events work and now I'm more confused than when I started.

我一直在寻找有关这些事件如何运作的清晰指南,现在我比开始时更加困惑。

Certain features of my site involve drag-and-drop. Currently mobile devices (or anything without a mouse) are supported by having the user select the item, tap the "move" button, then touch the drop point. While this works quite well (items are on a visible grid), it's not exactly as user-friendly as dragging.

我网站的某些功能涉及拖放。当前,通过让用户选择项目、点击“移动”按钮、然后触摸放置点来支持移动设备(或任何没有鼠标的设备)。虽然这很有效(项目位于可见的网格上),但它并不像拖动那样用户友好。

My initial understanding is that, wherever I assign element.onmousedown, element.onmousemoveand element.onmouseupI can simply also assign the same handler to element.ontouchstart, element.ontouchmoveand element.ontouchendrespectively.

我最初的理解是,只要我给你element.onmousedownelement.onmousemove而且element.onmouseup我可以简单地也将相同的处理程序element.ontouchstartelement.ontouchmoveelement.ontouchend分别。

However, that leaves the following questions:

但是,这留下了以下问题:

  • How do I get the coordinates of the touch point, and what is it relative to?
  • Will the view be panned (the default action of dragging) and if so is that cancellable?
  • How can I avoid interfering with multi-touch actions such as pinching to zoom if one finger happens to be on a draggable element?
  • 我如何获得接触点的坐标,它相对于什么?
  • 视图是否会被平移(拖动的默认操作),如果是,是否可以取消?
  • 如果一根手指碰巧位于可拖动元素上,如何避免干扰多点触控操作,例如捏合缩放?

采纳答案by joewright

You can determine coordinates by measuring device width/height (window.innerHeight/window.innerWidth).

您可以通过测量设备宽度/高度 (window.innerHeight/window.innerWidth) 来确定坐标。

This article is a good starting point for touch events and overriding them: http://www.html5rocks.com/en/mobile/touch/

这篇文章是触摸事件和覆盖它们的一个很好的起点:http: //www.html5rocks.com/en/mobile/touch/

Multi-touch gestures shouldn't interfere with the draggable elements. You can use conditionals in your event handlers if they are interfering: (event handler) if (event.touches === 1) handle the event

多点触控手势不应干扰可拖动元素。如果它们干扰,您可以在事件处理程序中使用条件: (event handler) if (event.touches === 1) handle the event

回答by Josiah

The other answers better address the original question, but for posterity who, like me, find this link trying to make an existing click/drag (mouse) function work on touch screens, this is a very bare bones solution.

其他答案更好地解决了原始问题,但对于像我一样发现此链接试图使现有的点击/拖动(鼠标)功能在触摸屏上工作的后代来说,这是一个非常简单的解决方案。

If you're adding event listeners, you can add a corresponding 'touchstart' line to your 'mousedown' like so:

如果您要添加事件侦听器,则可以将相应的 'touchstart' 行添加到您的 'mousedown' 中,如下所示:

 document.getElementById('throttle').addEventListener('mousedown', mouseDown, false);
 document.getElementById('throttle').addEventListener('touchstart', mouseDown, false);

Do the same for any mousemove (touchmove) and mouseup (touchend).

对任何 mousemove (touchmove) 和 mouseup (touchend) 执行相同的操作。

Within your functions, when you get the mouse coordinates, use:

在您的函数中,当您获得鼠标坐标时,请使用:

  var top = e.clientY || e.targetTouches[0].pageY; //the same syntax for the x value

That way it checks for a mouse click and drag first, then if that's undefined, it looks for a touch interaction.

这样它首先检查鼠标单击和拖动,然后如果未定义,则查找触摸交互。

Like I said, very barebones, but it worked to get me started.

就像我说的,非常准系统,但它让我开始工作。

回答by Endre Simo

Here is a short summary about differences between mobile and desktop screen coordinates: What is the difference between screenX/Y, clientX/Y and pageX/Y?

以下是关于移动和桌面屏幕坐标差异的简短总结:screenX/Y、clientX/Y 和 pageX/Y 之间有什么区别?

And a working example of implementing the touchmoveevent listener:

以及实现touchmove事件侦听器的工作示例:

 this.canvas.addEventListener("touchmove", function(e) {
        e.preventDefault();
        touchPosition(e);
    }, false);

var getCanvasPos = function(el) {
    var canvas = document.getElementById(el) || this.getCanvas();
    var _x = canvas.offsetLeft;
    var _y = canvas.offsetTop;

    while(canvas = canvas.offsetParent) {
        _x += canvas.offsetLeft - canvas.scrollLeft;
        _y += canvas.offsetTop - canvas.scrollTop;
    }

    return {
        left : _x,
        top : _y
    }
};

var touchPosition = function(e) {
    var mouseX = e.clientX - this.getCanvasPos(e.target).left + window.pageXOffset;
    var mouseY = e.clientY - this.getCanvasPos(e.target).top + window.pageYOffset;
    return {
        x : mouseX,
        y : mouseY
    };
};