JQuery 移动设备:在多个元素上进行单次触摸移动就像鼠标悬停一样
JQuery mobile: make a single touch-move over multiple elements behave like mouse hover
我看过很多similar questions,但令人惊讶的是它们完全不同
我想要一种方法,让使用触摸屏的用户能够一次将手指拖到页面上的多个元素上,并且当他的手指从一个元素移动到另一个元素时,让这些元素触发类似的事件如果鼠标移到它们上面。所以每个元素都会触发等同于 touchenter
和 touchleave
事件之类的东西。
JQuery 移动端支持多种触摸事件:touchstart
、touchend
、touchmove
、touchcancel
、tap
、swipe
, taphold
但我似乎无法使用它们来实现它。
假设我有 n 个元素,我有这样的代码:
function applyDown(idx){ /*...*/ }
function applyUp(idx){ /*...*/ }
function go(idx, fn){
return function(){
fn(idx);
}
}
for (var i = 0; i < n; i++){
$(".element_"+i).on("touchstart", go(i, applyDown));
$(".element_"+i).on("touchmove", go(i, applyDown));
$(".element_"+i).on("touchend", go(i, applyUp));
}
如果我开始触摸一个元素并滑动到另一个元素,然后松开,第二个元素永远不会调用 applyDown()
,而第一个元素只会在手指按下时调用 applyUp()
从屏幕上释放(而它应该在手指离开元素时立即调用)。
我怎样才能达到我想要的?
我在上面使用了 touchmove
,因为我认为它可以解决问题,但无论是否使用它,行为都是相同的。
这些元素实际上是复杂的 SVG 形状,所以我不知道它是否会排除一些 hacky(?) 替代方案,例如,使用 javascript 来计算手指在哪个元素上在任何时间点。
我最终使用了 hacky 解决方案:在给定触摸位置的情况下寻找 SVG 元素:
$(document).on("touchmove touchstart", function(event){
var x = event.originalEvent.touches[0].pageX;
var y = event.originalEvent.touches[0].pageY;
var e = document.elementFromPoint(x, y);
// remove existing hover effects
$(".element")
.attr("stroke-width", "1")
.attr("stroke", "#bbb")
.attr("fill", "#eee");
// add hover effect to matching element
$(e).filter(".element")
.attr("stroke-width", "2")
.attr("stroke", "#181")
.attr("fill", "#afa");
});
$(document).on("touchend", function(event){
$(".element")
.attr("stroke-width", "1")
.attr("stroke", "#bbb")
.attr("fill", "#eee");
});
我看过很多similar questions,但令人惊讶的是它们完全不同
我想要一种方法,让使用触摸屏的用户能够一次将手指拖到页面上的多个元素上,并且当他的手指从一个元素移动到另一个元素时,让这些元素触发类似的事件如果鼠标移到它们上面。所以每个元素都会触发等同于 touchenter
和 touchleave
事件之类的东西。
JQuery 移动端支持多种触摸事件:touchstart
、touchend
、touchmove
、touchcancel
、tap
、swipe
, taphold
但我似乎无法使用它们来实现它。
假设我有 n 个元素,我有这样的代码:
function applyDown(idx){ /*...*/ }
function applyUp(idx){ /*...*/ }
function go(idx, fn){
return function(){
fn(idx);
}
}
for (var i = 0; i < n; i++){
$(".element_"+i).on("touchstart", go(i, applyDown));
$(".element_"+i).on("touchmove", go(i, applyDown));
$(".element_"+i).on("touchend", go(i, applyUp));
}
如果我开始触摸一个元素并滑动到另一个元素,然后松开,第二个元素永远不会调用 applyDown()
,而第一个元素只会在手指按下时调用 applyUp()
从屏幕上释放(而它应该在手指离开元素时立即调用)。
我怎样才能达到我想要的?
我在上面使用了 touchmove
,因为我认为它可以解决问题,但无论是否使用它,行为都是相同的。
这些元素实际上是复杂的 SVG 形状,所以我不知道它是否会排除一些 hacky(?) 替代方案,例如,使用 javascript 来计算手指在哪个元素上在任何时间点。
我最终使用了 hacky 解决方案:在给定触摸位置的情况下寻找 SVG 元素:
$(document).on("touchmove touchstart", function(event){
var x = event.originalEvent.touches[0].pageX;
var y = event.originalEvent.touches[0].pageY;
var e = document.elementFromPoint(x, y);
// remove existing hover effects
$(".element")
.attr("stroke-width", "1")
.attr("stroke", "#bbb")
.attr("fill", "#eee");
// add hover effect to matching element
$(e).filter(".element")
.attr("stroke-width", "2")
.attr("stroke", "#181")
.attr("fill", "#afa");
});
$(document).on("touchend", function(event){
$(".element")
.attr("stroke-width", "1")
.attr("stroke", "#bbb")
.attr("fill", "#eee");
});