Javascript 在缩放视口时,如何从指针事件和触摸事件中获得相同的坐标?

Javascript 在缩放视口时,如何从指针事件和触摸事件中获得相同的坐标?,javascript,html,google-chrome,mobile,pointer-events,Javascript,Html,Google Chrome,Mobile,Pointer Events,我尝试使用指针事件(例如pointerdown)而不是将触摸(例如touchtstart)和鼠标(例如mousedown)事件结合起来计算输入事件坐标 var bodyElement = document.body; bodyElement.addEventListener("touchstart", function(e) {console.log("touch: " + e.changedTouches[0].clientX + " " + e.changedTouches[0].clie

我尝试使用指针事件(例如
pointerdown
)而不是将触摸(例如
touchtstart
)和鼠标(例如
mousedown
)事件结合起来计算输入事件坐标

var bodyElement = document.body;

bodyElement.addEventListener("touchstart", function(e) {console.log("touch: " + e.changedTouches[0].clientX + " " + e.changedTouches[0].clientY);});
bodyElement.addEventListener("pointerdown", function(e) {console.log("point: " + e.clientX + " " + e.clientY);});
在视口被缩放之前,一切都可以正常工作(例如,android chrome会缩放网页,chrome开发工具中的设备工具栏缩放系数不是100%,…)。指针事件随后开始报告完全错误的值

您可以在以下屏幕截图中观察到错误:

1) 视口缩放到100%,300px*300px div单击到右下角的录像机:

2) 视口缩放到150%,300px*300px div单击到右下角:

你们知道如何从指针事件中获得正确的坐标吗

编辑:

添加了jsiddle:

以div为目标,而不是可能改变实际div方向的“相对”主体

试试这个:

const dostuffwithdiv = () =>{
  var u = document.getElementById('uniqueDiv');

  u.addEventListener("touchstart", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.targetTouches[0].pageX - rect.left;
    var y = e.targetTouches[0].pageY - rect.top;
    var msg = `touch: ${x} ${y}`;
    console.log(msg);
  });
  u.addEventListener("pointerdown", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.clientX - rect.left;
    var y = e.clientY - rect.top;
    var msg = `point: ${x} ${y}`;
    console.log(msg);
  });
}

document.onreadystatechange = dostuffwithdiv(); //since this is jsfiddle this will work
//but on a real frontend you'd want to do something more like this:
//document.addEventListener("DOMContentLoaded", dostuffwithdiv);
这是一个提琴,尽管它的最底层是监听不同的事件,但由于JSFIDLE内部的工作方式,我不得不修改最后一行。我希望这是有意义的,如果它不只是问


这是我能得到的最接近的。我认为chrome最近改变了这些设备的运行方式和性能。。。我对-insert explicit remark-touchstart或pointerdown事件的理解不够深入,但这是我所能理解的最接近的:

html(请注意,我删除了您正在应用的边框,因为这会造成额外的麻烦,如果绝对必要,您必须在以后进行计算)


听起来像是补偿问题。如果可以的话,可以在stackoverflows个人编辑器或JSFIDLE或同等工具中获得此功能的工作演示,我可以提供帮助。希望您能够复制它。不幸的是,更改侦听器目标并不会改变行为。你可以在下面的截图中看到输出:我点击了div的中间,触摸报告正确的中间(162x149)和指针完全关闭。尝试更新的代码,我调整它现在工作在jsFoDeld.仍然是相同的。边界矩形在TouchEvent和PointerEvent中都是相同的,因此它不会对这两个事件产生不同的影响。你能重现我描述的问题吗?问题是什么,你想把两者区别开来?我明白问题所在!我更新了我的chrome,现在它被破坏了:)给我几分钟时间修改。如果你想将这两个事件合并到同一个事件中,你可以检查传入的事件,并相应地执行不同的逻辑。就像我问题顶部提到的,我以前使用鼠标和触摸事件的组合-类似于您的方法。希望能够改进指针事件侦听器,而不是返回鼠标+触摸。所以只需同时侦听这两个事件。类似于u.addEventListener('touchstart mouseup',function(){if(e.type=='touchstart'){//do touchstart相关内容}或者{//do mouseup内容});
<body style="margin:0; padding: 0;">
    <div id="uniqueDiv" style="width:300px;height:300px;background-color: black;"></div>
</body>
const dostuffwithdiv = () =>{
  var u = document.getElementById('uniqueDiv');

  u.addEventListener("touchstart", e=> {
    var rect = e.target.getBoundingClientRect();
    var x = e.targetTouches[0].clientX - rect.left;
    var y = e.targetTouches[0].clientY - rect.top;
    var msg = `touch: ${x} ${y}`;
    console.log(msg);
  });
  u.addEventListener("mouseup", e=> {
    var msg = `point: ${e.clientX} ${e.clientY}`;
    console.log(msg);
  });
}

// document.addEventListener("DOMContentLoaded", dostuffwithdiv);
document.onreadystatechange = dostuffwithdiv();