javascript - iOS 和 Android 中滚动页面的触摸事件偏移不正确

标签 javascript ios html canvas

我们有一个网页,其中包含一些允许用户绘制的 div/canvas 标签:

 <div id="Drawing" class="FormField" style="position: absolute; top: 444px; left: 121px;
      width: 302px; height: 185px; font-size: 10pt;">
      <canvas id="DrawingCanvas" class="InkFormField" width="302" height="185" style=""></canvas>
 </div>
 <div id="Picture" class="FormField" style="position: absolute; top: 915px; left: 121px;
      width: 302px; height: 167px; font-size: 10pt;">
      <canvas id="PictureCanvas" class="InkFormField" width="302" height="167" style=""></canvas>
 </div>

第二个 div/canvas(顶部:915px)最初是不可见的,但可以滚动到并在上面上墨。

绘图是非常直接的代码,可在桌面浏览器上正常工作(使用适当的鼠标事件)。对于 iPad,我们需要使用触摸事件来确定要绘制的点位置:

        var touchX = e.changedTouches[0].screenX - canvasLeft;
        var touchY = e.changedTouches[0].screenY - canvasTop;

(其中 canvasLeft 和 canvasTop 是 Canvas 的页面相对偏移量)。

一切正常,即使在滚动到第二个 div/canvas 之后也是如此。

但是,一旦将外部添加到上述代码中(使用overflow: auto),touchX 和 touchY 值在 div 之后不再正确滚动:

  <div style="overflow: auto">
     <div id="Drawing" class="FormField" style="position: absolute; top: 444px; left: 121px;
          width: 302px; height: 185px; font-size: 10pt;">
          <canvas id="DrawingCanvas" class="InkFormField" width="302" height="185" style=""></canvas>
     </div>
     <div id="Picture" class="FormField" style="position: absolute; top: 915px; left: 121px;
          width: 302px; height: 167px; font-size: 10pt;">
          <canvas id="PictureCanvas" class="InkFormField" width="302" height="167" style=""></canvas>
     </div>
  </div>

事实上,它们似乎完全偏离了滚动的数量!根据文档,screenY 属性应该考虑滚动(但可能是指页面滚动,而不是外部 div 滚动)。

触摸事件是否有不同的属性报告相对于滚动 div 的 x 和 y 偏移量,以便可以正确绘制点?

或者,是否有跟踪滚动量的方法,以便可以将适当的偏移量应用于 touchX 和 touchY 的计算?

最佳答案

这是我的鼠标/触摸代码。试一试。它应该适合你:

通过触摸事件,您可以执行以下操作:'

if (e.targetTouches) e = e.targetTouches[0];

在你调用它之前。

function getMouse(e, canvas) {
  var element = canvas, offsetX = 0, offsetY = 0, mx, my;

  // Compute the total offset
  if (element.offsetParent !== undefined) {
    do {
      offsetX += element.offsetLeft;
      offsetY += element.offsetTop;
    } while ((element = element.offsetParent));
  }

  // Add padding and border style widths to offset
  // Also add the <html> offsets in case there's a position:fixed bar
  offsetX += _stylePaddingLeft + _styleBorderLeft + _htmlLeft;
  offsetY += _stylePaddingTop + _styleBorderTop + _htmlTop;

  mx = e.pageX - offsetX;
  my = e.pageY - offsetY;

  return {x: mx, y: my};
}

这些偏移量如下,假设你的 Canvas 被称为“ Canvas ”:

_stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)      || 0;
_stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)       || 0;
_styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10)  || 0;
_styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)   || 0;
// <html> can have a margin (typically seen with position:fixed bars)
var html = document.body.parentNode;
_htmlTop = html.offsetTop;
_htmlLeft = html.offsetLeft;

关于javascript - iOS 和 Android 中滚动页面的触摸事件偏移不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9611455/

相关文章:

javascript - 从网站访问动态数据

php - 使用javascript检查MySql中的用户验证

ios - Swift UICollectionView 委托(delegate)执行 segue

html - 如何向六边形元素添加文本?

HTML 邮寄表单 : prefill subject and body

javascript - 自定义 JQuery 在 WordPress 中不起作用

Javascript 数组 - 合并多个数组帮助

javascript - 16 :9 Aspect Ratio App & Background (Accounting for space taken by the Nav)

ios - 如何在 Cordova 中播放 HTML5 视频时忽略铃声设置

ios - 无法在 IOS 模拟器上运行 React Native 应用程序