JavaScript:触摸事件在 iPad 上起作用,但在 iPhone 上不起作用
JavaScript: Touch Events Working on iPad but not iPhone
为 iPad 和 iPhone 编写 JS 触摸事件有什么区别吗?我已经阅读了大量文档,据我所知,两者的工作方式应该相同。
我有一个拖放游戏,基本上你从龙下面抓取一枚硬币并将其拖到你的金库中。拖动适用于 iPad,但不适用于 iPhone。我想弄清楚为什么。
游戏,供参考:https://codeeverydamnday.com/projects/dragondrop/dragondrop.html
JS,删节为这个问题的相关代码(为了清楚起见,有注释):
var dragndrop = (function() {
var myX = "";
var myY = "";
// The coin's starting X and Y coordinate positions
var coin = "";
// The coin you start touching / dragging
function touchStart(e) {
e.preventDefault();
// Prevents default behavior of scrolling when you touch/drag on mobile
var coin = e.target;
var touch = e.touches[0];
var moveOffsetX = coin.offsetLeft - touch.pageX;
var moveOffsetY = coin.offsetTop - touch.pageY;
// Defines offset between left edge of coin and where you place your finger on it
coin.addEventListener('touchmove', function() {
var positionX = touch.pageX+moveOffsetX;
var positionY = touch.pageY+moveOffsetY;
// Defines the X-Y coordinates of wherever you stop dragging
coin.style.left = positionX + 'px';
coin.style.top = positionY + 'px';
// Updates the coin's X-Y coordinates with the new positions
}, false)
}
document.querySelector('body').addEventListener('touchstart', touchStart, false);
})();
如果有帮助,我每次在 Chrome Dev Tools 模拟器中点击/点击 iPad 屏幕时都会收到此控制台日志错误:
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.
这个错误似乎并没有阻止拖动在 iPad 上工作,但我不确定它是否与拖动在移动设备上不起作用有关?我尝试根据我看到的其他 Stack Overflow 问题添加一些东西来修复错误(例如,在我的 CSS 中添加 touch-action: none;
,但错误仍然存在)。
有人看到我的代码有什么问题吗?我很想让这款游戏可以在手机上玩,因为大多数人都会通过这种方式访问它!
对于 touch-start
和 touch-move
事件,passive 选项的默认值设置为 true
,它为真意味着您的函数不会调用 preventDefault
禁用滚动。
只需将 passive
值设置为 false
即可解决您的问题。
var dragndrop = (function() {
var myX;
var myY;
var coin;
function touchStart(e) {
e.preventDefault();
coin = e.target;
const touch = e.touches[0];
const moveOffsetX = whichArt.offsetLeft - touch.pageX;
const moveOffsetY = whichArt.offsetTop - touch.pageY;
coin.addEventListener("touchmove", touchMove, { passive: false });
function touchMove(e) {
const touch = e.touches[0];
const positionX = touch.pageX + moveOffsetX;
const positionY = touch.pageY + moveOffsetY;
coin.style.left = `${positionX}px`;
coin.style.top = `${positionY}px`;
}
}
document.body.addEventListener('touchstart', touchStart, { passive: false });
})();
编辑
我查看了您链接的网站上的代码,我意识到硬币没有被拖动的原因之一是因为我们正在使用 touch
以及 once
选项我传给了touchmove
活动
每当使用touchmove
事件时,我们必须使用新的触摸来获取屏幕上的pageX
和pageY
位置,我决定为touchmove
事件,因为每当调用 touchstart
函数时,由于匿名函数处理程序,都会注册一个新的 touchmove
事件。
因此为其创建和命名函数将防止添加相同的函数。
为 iPad 和 iPhone 编写 JS 触摸事件有什么区别吗?我已经阅读了大量文档,据我所知,两者的工作方式应该相同。
我有一个拖放游戏,基本上你从龙下面抓取一枚硬币并将其拖到你的金库中。拖动适用于 iPad,但不适用于 iPhone。我想弄清楚为什么。
游戏,供参考:https://codeeverydamnday.com/projects/dragondrop/dragondrop.html
JS,删节为这个问题的相关代码(为了清楚起见,有注释):
var dragndrop = (function() {
var myX = "";
var myY = "";
// The coin's starting X and Y coordinate positions
var coin = "";
// The coin you start touching / dragging
function touchStart(e) {
e.preventDefault();
// Prevents default behavior of scrolling when you touch/drag on mobile
var coin = e.target;
var touch = e.touches[0];
var moveOffsetX = coin.offsetLeft - touch.pageX;
var moveOffsetY = coin.offsetTop - touch.pageY;
// Defines offset between left edge of coin and where you place your finger on it
coin.addEventListener('touchmove', function() {
var positionX = touch.pageX+moveOffsetX;
var positionY = touch.pageY+moveOffsetY;
// Defines the X-Y coordinates of wherever you stop dragging
coin.style.left = positionX + 'px';
coin.style.top = positionY + 'px';
// Updates the coin's X-Y coordinates with the new positions
}, false)
}
document.querySelector('body').addEventListener('touchstart', touchStart, false);
})();
如果有帮助,我每次在 Chrome Dev Tools 模拟器中点击/点击 iPad 屏幕时都会收到此控制台日志错误:
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.
这个错误似乎并没有阻止拖动在 iPad 上工作,但我不确定它是否与拖动在移动设备上不起作用有关?我尝试根据我看到的其他 Stack Overflow 问题添加一些东西来修复错误(例如,在我的 CSS 中添加 touch-action: none;
,但错误仍然存在)。
有人看到我的代码有什么问题吗?我很想让这款游戏可以在手机上玩,因为大多数人都会通过这种方式访问它!
对于 touch-start
和 touch-move
事件,passive 选项的默认值设置为 true
,它为真意味着您的函数不会调用 preventDefault
禁用滚动。
只需将 passive
值设置为 false
即可解决您的问题。
var dragndrop = (function() {
var myX;
var myY;
var coin;
function touchStart(e) {
e.preventDefault();
coin = e.target;
const touch = e.touches[0];
const moveOffsetX = whichArt.offsetLeft - touch.pageX;
const moveOffsetY = whichArt.offsetTop - touch.pageY;
coin.addEventListener("touchmove", touchMove, { passive: false });
function touchMove(e) {
const touch = e.touches[0];
const positionX = touch.pageX + moveOffsetX;
const positionY = touch.pageY + moveOffsetY;
coin.style.left = `${positionX}px`;
coin.style.top = `${positionY}px`;
}
}
document.body.addEventListener('touchstart', touchStart, { passive: false });
})();
编辑
我查看了您链接的网站上的代码,我意识到硬币没有被拖动的原因之一是因为我们正在使用 touch
以及 once
选项我传给了touchmove
活动
每当使用touchmove
事件时,我们必须使用新的触摸来获取屏幕上的pageX
和pageY
位置,我决定为touchmove
事件,因为每当调用 touchstart
函数时,由于匿名函数处理程序,都会注册一个新的 touchmove
事件。
因此为其创建和命名函数将防止添加相同的函数。