gpt4 book ai didi

javascript - 如何检测元素外的touchend事件

转载 作者:技术小花猫 更新时间:2023-10-29 12:52:49 31 4
gpt4 key购买 nike

我正在尝试处理按钮点击。 “按钮”是一个自定义的 div,也可以包含子元素。单击回调应该在用户在元素内单击和释放时触发。如果用户在内部单击然后在外部拖动并释放,则处理程序不应触发。我需要让它在桌面和移动设备上都能正常工作,因此我使用了 mousedown/mouseuptouchstart/touchend 事件。

我需要将按钮类从“按下”更改为“正常”,即使用户在外面释放,所以我需要添加一个监听器来捕获文档上的释放事件:

    var $myElement = $("#myelement"); //This is a div and can also contain children.

$myElement.on("mousedown touchstart", function(e){

$(this).addClass("pressed");

$(document).on("mouseup touchend", function listener(e){
$myElement.removeClass("pressed");

$(document).off("mouseup touchend", listener);

var $target = $(e.target);
if ($target.is($myElement) || $target.parents().is($myElement)){
//FIXME
alert("Inside!");

//do something here
return false;
} else {
//FIXME
alert("Outside!");

//let event bubble
}
});

return false;
});

它在点击时工作正常,但在触摸事件时却无法正常工作。我已经在 Android 版 Chrome 中对此进行了测试,当按下该元素,然后拖出时,“内部!”显示警报。

问题出在这种情况下:

if ($target.is($myElement) || $target.parents().is($myElement)){

我正在尝试检查 touchend 事件是否发生在按钮或任何子项中。如果按钮没有子按钮,当点击它然后在外面释放时,OR 子句的第一部分解析为真。如果按钮有子项并且我在子项中单击,然后在屏幕的任何其他部分释放,则子句的第二部分为真。

这段代码有什么问题?

提前致谢。

更新
我也在 BlackBerry 10 中测试过它,结果相同。显然 touchend 事件的目标是按钮(或子元素),即使我在外部单击也是如此。它应该是这样工作的吗?

更新
这就是为什么。这是 what the W3C docs say about the event :

The target of this event must be the same Element that received the touchstart event when this touch point was placed on the surface, even if the touch point has since moved outside the interactive area of the target element.

这对我来说毫无意义,但无论如何这解释了我的问题。我假设将在释放手指的元素上调用 touchend 事件。是否可以使用不同的方法检测到手指在外面松开?

更新
我试图获取 touchevent 的坐标,以便使用 document.elementFromPoint 获取那里的元素。问题是此事件不包含坐标(changedTouchestouches 列表为空)。我已经彻底检查了调试器中的事件,除了原始事件之外,没有办法从中检索坐标。然后我想我可以缓存最后一个 touchmove 事件并从那里获取坐标,但是这个事件又没有自己的坐标!为什么这两个事件在没有用的情况下存在?我在 iOS、Android 和 BB10 中测试了这种方法,结果相同。

我放弃了。即使用户点击外部,我也会调用回调。我不敢相信这是 2013 年的人,没有(简单的)方法可以做到这一点?我可以使用拖放 api 但根据 this它在移动设备上不受支持(一定喜欢移动网络开发)。

最佳答案

终于(几乎)让它在 BB10 和 Android 中运行。我在问题更新中留下了一系列问题,所以总结一下:touchend 事件目标与 touchstart 相同,并且它没有坐标( API 设计者出于某种原因决定将它们“隐藏”在 originalEvent 属性中:)。所以我从 changedTouches[0].pageXchangedTouches[0].pageY 中检索触摸结束坐标,然后使用 获取释放手指的元素>document.elementFromPoint。 (在向此方法提供事件坐标之前,您必须将滚动偏移量添加到 x 和 y)。然后,如果此时的元素是按钮(或者是按钮的子元素),我会处理点击。

    var $myElement = $("#myelement"); //This is a div and can also contain children.
var startEvent = touchDevice() ? "touchstart" : "mousedown";
var releaseEvent = touchDevice() ? "touchend" : "mouseup";

$myElement.on(startEvent, function(e){

$(this).addClass("pressed");

$(document).on(releaseEvent, function listener(e){
$myElement.removeClass("pressed");

$(document).off(releaseEvent, listener);

var $target = null;
if(e.type === "mouseup"){
$target = $(e.target);
} else {
var x = e.originalEvent.changedTouches[0].pageX - window.pageXOffset;
var y = e.originalEvent.changedTouches[0].pageY - window.pageYOffset;
var target = document.elementFromPoint(x, y);

if(target){
$target = $(target);
}
}

if ($target !== null && ($target.is($myElement) || $target.parents().is($myElement))){
//FIXME
alert("Inside!");

//callback here
return false;
} else {
//FIXME
alert("Outside!");
}
});

return false;
});

现在我遇到了一个新问题:在 iOS 中,点击事件以某种方式被复制。但这值得一个不同的问题(如果不存在的话)。

关于javascript - 如何检测元素外的touchend事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17650170/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com