- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这也适用于其他浏览器,但主要目标是 Firefox 和 Chrome。
我已经注册了所有指针事件监听器并且必须注册鼠标按下和鼠标向上监听器来获取按钮状态变化(指针事件中的按钮状态不准确或“和弦”)
但即使我对所有指针执行 event.preventDefault():over、enter、down、up、out 和 leave 事件(pointerType mouse for down 除外,因为它会禁用 mousedown 和 mouse up 监听器)我还有其他问题:
多点触控(多于一根手指)将被接管并执行页面缩放操作,使我的应用中的多点触控变得无用。
如果页面上有滚动条,触摸平移/滚动操作将接管单次触摸。
preventDefault() 未在操作系统(即:windows 10)中正确实现,在我的元素上向下的指针也会生成合成鼠标按下并将鼠标合成移动到触摸位置。我可以用困惑的代码忽略合成的向下和向上事件)但它会将鼠标放在意想不到的位置,并防止在需要时同时使用鼠标和触摸作为单独的输入。 (解决这个问题可能需要在 DOM 元素本身而不是每个事件的基础上设置一个标志,因为内部事件队列将在操作系统和浏览器调度的事件之间放置延迟 - 我已经在我的 native 应用程序中解决了这个问题)
我正在使用 Web 开发人员控制台进行测试,因此我可以记录状态 - 我不知道这是否会影响事情。
我在 Chrome 上也有同样的触摸平移/缩放缺乏控制。Chrome 和 Firefox 上的鼠标上/下行为明显不同,因此需要单独的代码路径。对战
对于代码迷——注意这是一个接口(interface)设备“前端”“webasm”(游戏或生活游戏)引擎:)
目标是为任何进入 Canvas 元素的指针(未被另一个元素的处理程序捕获)获取“干净的原始”事件流。使用捕获的指针镜像所有受支持设备上所有按钮的状态,直到捕获丢失。还能够将鼠标和触摸(以及任何其他支持的设备)用作单独的设备,忽略所有合成事件并希望关闭我正在收听的一个设备被我正在收听的另一个设备模拟的任何东西(所以他们不'战斗)。还可以完全控制对事件执行的操作,直到丢失指针的事件流捕获为止。我想捕获在触摸设备(平板电脑、面板、屏幕等)的元素上发生“主要”触摸之后和同时发生的所有触摸,如果不使用我们的 UI,则可以选择让它们“掉落” .
以下是附加到“ Canvas ”元素的事件处理程序。他们除了将数据转发给 webasm 应用程序外什么都不做。当然会在工作后清理干净。这是 Firefox 代码。 :)
canvas.addEventListener('pointerover', this.onPeOED, false);
canvas.addEventListener('pointerenter', this.onPeOED, false);
canvas.addEventListener('pointerdown', this.onPeOED, false);
canvas.addEventListener('pointermove', this.onPeMove, false);
canvas.addEventListener('pointerup', this.onPeUOCL, false);
canvas.addEventListener('pointerout', this.onPeUOCL, false);
canvas.addEventListener('pointercancel', this.onPeUOCL, false);
canvas.addEventListener('pointerleave', this.onPeUOCL, false);
canvas.addEventListener('mousedown', this.onMouseDown, false);
canvas.addEventListener('mouseup', this.onMouseUp, false);
onPeOED: (function(e) {
var handled = 0;
var code = e.type.charCodeAt(7);
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
var flags = (1 << (9 + 16)); // fPointerInside
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
flags = 0;
}
// o == over, e == enter, d == down,
if(code == 100) { // 100 == 'd'
flags |= (1 << (10 + 16)); // in contact << 16
}
target._mousePointerId_ = -1;
switch(e.pointerType) {
case 'mouse':
target._mousePointerId_ = e.pointerId;
if(code == 100) { // 100 == 'd' handled by onMouseDown
target.setPointerCapture(e.pointerId);
return;
}
flags |= 0x0100; // UID_MOUSE << 8
break;
case 'pen':
flags |= 0x0200; // UID_STYLUS << 8
break;
case 'touch':
flags |= 0x0300; // UID_FINGER << 8
break;
default:
Module.print("unknown UID");
break;
}
if(code == 100) { // 100 == 'd'
target.setPointerCapture(e.pointerId);
}
// Module.print("ON uid " + e.pointerType + " " + e.type + " buttons " + e.which + " inside " + ((flags & (1 << (9 + 16))) != 0));
if(e.buttons != 0) {
flags |= (e.buttons << 16) | (1 << (10 + 16)); // fPointerInContact
}
handled = ccall('onPointerFlagsOn', 'number', EngineConnector.number_11_Sig,
// target type|flags time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
(code | flags),
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
e.preventDefault();
}),
onMouseDown: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
// Module.print("mouse ME down " + target._mousePointerId_);
if(target._mousePointerId_ < 0 || posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
Module.print("mouse ignored");
e.preventDefault();
return; // ignore downs while outide element
}
var wentDown = (e.buttons & (~(target._mouseButtons_)));
target._mouseButtons_ = e.buttons;
// Module.print("mouse down " + e.buttons + " went down " + wentDown);
handled = ccall('onPointerFlagsOn', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
// 'd' UID_MOUSE fPointerInside fPointerInContact
(100 | 0x0100 | (1 << (9 + 16)) | (1 << (10 + 16)) | (wentDown << 16)),
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
// e.preventDefault();
}),
fireButtonUp: (function(e, buttons) {
// Module.print("ME fire up true " + buttons );
var ptrId = e.currentTarget._mousePointerId_;
if(ptrId < 0) {
return;
}
ccall('onPointerFlagsOff', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[e.currentTarget._CPPHandle_,
(117 | 0x0100 | (buttons << 16)), // 117 == 'u' == 'up', 1 == UID_MOUSE
e.timeStamp,
ptrId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
e.clientX,
e.clientY,
0,
]);
}),
// up/leave
onMouseUp: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
// we have to kill ALL the buttons
EngineConnector.fireButtonUp(e,target._mouseButtons_ | (1 << 10));
target._mouseButtons_ = 0;
} else {
var released = (target._mouseButtons_ & (~e.buttons)); // will leave the one we released
target._mouseButtons_ = e.buttons;
if(e.buttons == 0) {
released |= (1 << 10); // fPointerInContact
}
EngineConnector.fireButtonUp(e,(released | (1 << 9)));
}
e.preventDefault();
}),
onPeMove: (function(e) {
var target = e.currentTarget;
var posX = e.clientX;
var posY = e.clientY;
var flags = (1 << 9);
if(posX < 0 || posY < 0 || posX >= target.width || posY >= target.height) {
flags = 0;
}
var pType = e.pointerType.charCodeAt(0);
if(pType == 109) { // 'm' == 109
// MOUSE
if(target._mousePointerId_ < 0) {
e.preventDefault();
return;
}
} else {
Module.print("move !!!");
}
flags |= pType; // 'm', 'p', 't'
handled = ccall('onPointerMove', 'number', EngineConnector.number_11_Sig,
// target flags time id screenX screenY pageX pageY targetX targetY pressure
[ target._CPPHandle_,
flags,
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure
]);
}),
onPeUOCL: (function(e) {
var code = e.type.charCodeAt(7);
var target = e.currentTarget;
target._poinsePointerId_ = -1;
switch(e.pointerType) {
case 'mouse':
target._poinsePointerId_ = e.pointerId;
if(code == 117) { // 117 == 'u' mouseup handled by mouse event handler
return;
}
code |= 0x0100; // UID_MOUSE << 8
// let leave and cancel get reported
break;
case 'pen':
code |= 0x0200; // UID_STYLUS << 8
if(code == 117) {
code |= ((1 << 16) << e.which);
}
break;
case 'touch':
code |= 0x0300; // UID_FINGER << 8
if(code == 117) {
code |= ((1 << 16) << e.which);
}
break;
default:
Module.print("unknown UID");
break;
}
var posX = e.clientX;
var posY = e.clientY;
if(posX >= 0 && posY >= 0 || posX < target.width || posY < target.height) {
code |= (1 << (9 + 16));
}
// Module.print("off uid " + e.pointerType + " " + e.type + " buttons " + e.which + " inside " + ((code & (1 << (9 + 16))) != 0));
var handled = 0;
handled = ccall('onPointerFlagsOff', 'number', EngineConnector.number_11_Sig,
// target type time id screenX screenY pageX pageY targetX targetY pressure
[e.currentTarget._CPPHandle_,
code,
e.timeStamp,
e.pointerId,
e.screenX,
e.screenY,
e.pageX,
e.pageY,
posX,
posY,
e.pressure,
]);
e.preventDefault();
}),
将近 30 年前,当我致力于让 Microsoft 创建 DirectX 时,我引用了一句 - 它又是 Deja Vous :)
“对于任何真正灵活的系统,必须能够使用它提供的设施从头开始实现该系统。”
最佳答案
我很惊讶没有人提到这个。解决方案是 canvas.setAttribute('style','touch-action: none');
https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
顺便说一句,在 Chrome 上可以正常工作 99%。
Firefox 仍会通过合成点击,我必须将其放入讨厌的事件计时代码中才能过滤掉。
两者都无法通过触摸模拟禁用 Windows 10 鼠标,因此无法同时使用鼠标和触摸。我还没有找到让用户在 Windows 10 上禁用它的方法。无论如何,我不想在整个系统范围内禁用它,而只是在点击和触摸/拖动 Canvas 元素时才禁用它。
关于javascript - 如何使用指针事件覆盖 firefox 和 chrome 中的触摸缩放和平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54621987/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!