jQuery在taphold事件之后调用click事件
我正在使用Jquery和Jquery Mobile为Android开发一个PhoneGap应用程序 我有一个需要两个事件绑定到列表中每个项目的项目列表。我需要一个“点击”事件和一个“点击”事件。我遇到的问题是,当我执行“taphold”时,会触发正确的“taphold”事件。但是,一旦我释放,click事件也会触发。如何防止点击事件在点击后触发 代码:jQuery在taphold事件之后调用click事件,jquery,jquery-mobile,cordova,Jquery,Jquery Mobile,Cordova,我正在使用Jquery和Jquery Mobile为Android开发一个PhoneGap应用程序 我有一个需要两个事件绑定到列表中每个项目的项目列表。我需要一个“点击”事件和一个“点击”事件。我遇到的问题是,当我执行“taphold”时,会触发正确的“taphold”事件。但是,一旦我释放,click事件也会触发。如何防止点击事件在点击后触发 代码: 函数LoadMyItems(项目){ 对于(项目中的变量idx) { var itemLine=''+ '' + items[idx]。item
函数LoadMyItems(项目){
对于(项目中的变量idx)
{
var itemLine=''+
'' +
items[idx]。item.name+
'';
$(“#我的列表”)。追加(“”+itemLine+” );
$('#my_item_uu'+items[idx].user_item_id).bind('tapphold',{userItem:items[idx]},ShowMyItemInfo);
$(“#my_item_uuu”+items[idx].user_item_id).bind('click tap',{userItem:items[idx]},FitMyUpgradeItem);
log('UserItem'+items[idx].user\u item\u id+'已加载并绑定事件');
}
$(“#我的_项_加载程序”).hide();
myScroll.refresh();
}
根据下面的建议,以下是我的结论。这在iScroll对象内部工作
function LoadMyItems(items) {
for(var idx in items)
{
var itemLine = '<div class="my_item" id="my_item_'+items[idx].user_item_id+'">' +
'<img class="item_icon_32" src=./images/graphicFiles/Icon48/'+items[idx].item.graphic.graphicFiles.Icon48.filename+' />' +
items[idx].item.name+
'</div>';
$('#my_list').append('<li>'+itemLine+'</li>');
(function(index) {
var tapTime = 0;
var xPos = 0;
var yPos = 0;
$('#my_item_'+items[index].user_item_id).bind('vmousedown vmouseup', function (event) {
if (event.type == 'vmousedown') {
tapTime = new Date().getTime();
xPos = event.pageX;
yPos = event.pageY;
var timer = setTimeout(function() {
var duration = (new Date().getTime() - tapTime);
var xDiff = Math.abs(mouseXPos - xPos);
var yDiff = Math.abs(mouseYPos - yPos);
if(duration >= 700 && (yDiff <= 40 || mouseXPos == 0))
ShowItemInfo(items[index].item);
},750);
} else {
//event.type == 'vmouseup'
var duration = (new Date().getTime() - tapTime);
var xDiff = Math.abs(event.pageX - xPos);
var yDiff = Math.abs(event.pageY - yPos);
tapTime = new Date().getTime();
if (duration < 699 && yDiff <= 40) {
//this is a tap
FitMyUpgradeItem(items[index]);
}
}
});
$('#my_item_'+items[index].user_item_id).bind('touchmove',function(event) {
event.preventDefault();
});
})(idx);
console.log('UserItem '+items[idx].user_item_id+' loaded and events bound');
}
$('#my_items_loader').hide();
myScroll.refresh();
}
函数LoadMyItems(项目){
对于(项目中的变量idx)
{
var itemLine=''+
'' +
items[idx]。item.name+
'';
$(“#我的列表”)。追加(“”+itemLine+” );
(功能(索引){
var-tapTime=0;
var-xPos=0;
var-yPos=0;
$('#我的项目'+items[index].用户项目id).绑定('vmousedown-vmouseup',函数(事件){
如果(event.type==“vmousedown”){
tapTime=newdate().getTime();
xPos=event.pageX;
yPos=event.pageY;
var timer=setTimeout(函数(){
var duration=(new Date().getTime()-tapTime);
var xDiff=Math.abs(mousexps-xPos);
var yDiff=Math.abs(mouseYPos-yPos);
如果(持续时间>=700&&(yDiff使用点击\v点击并点击保持——点击事件在点击保持后触发两次
$('#my_item_'+items[idx].user_item_id).bind('vclick', ...
$('#my_item_'+items[idx].user_item_id).bind('taphold', ...
在本例中,点击实际上不会在点击后调用。请在此处检查:
编辑:
jQuery Mobile自动将触摸事件绑定到某些元素
将iScroll与jquerymobile结合起来,绑定
将函数与“touchmove”事件分开,并防止事件发生
冒泡(event.preventDefault())。通过执行此jQuery移动
在用户交互时将无法处理触摸事件
使用iScroll元素
也
信贷而不是使用点击
和点击
(我曾尝试使用该功能,但遇到了相同的问题,这似乎是点击
事件的固有问题)您可以使用vmousedown
并设置一个标志,然后绑定到vmouseup
以确定它是一个点击
还是一个点击保持
:
var tapTime = 0;
$('#my_item_'+items[idx].user_item_id).bind('vmousedown vmouseup', function (event) {
if (event.type == 'vmousedown') {
tapTime = new Date().getTime();
} else {
//event.type == 'vmouseup'
//here you can check how long the `tap` was to determine what do do
var duration = (new Date().getTime() - tapTime);
if (duration > 3000) {
//this is a tap-hold
ShowMyItemInfo(items[idx]);
} else {
//this is a tap
FitMyUpgradeItem(items[idx]);
}
}
});
要使其正常工作,您必须在循环代码周围添加IIFE,或者更改ShowMyItemInfo(items[idx]);
以在不引用更改循环每次迭代的变量的情况下工作。创建IIFE的简单方法是只使用$。each()
。否则,您的循环将如下所示:
for(var idx in items)
{
(function (idx) {
...
})(idx);
}
$('#button').on('tap',function(){
console.log('tap!');
}).on('taphold',function(){
console.log('taphold!');
});
IIFE=立即调用的函数表达式。它允许我们对传入IIFE的变量的当前状态进行“快照”。因此,当我们传入idx
(从技术上讲,第二个实例是正在传入的变量,第一个实例是IIFE中可用的变量,为了简单起见,可以将其更改为类似于ids\u new
)的内容),传入的值会在触发tap
事件处理程序时保存
更新
您还可以设置超时来确定tapphold
,而不是使用vmouseup
事件:
//setup a timer and a flag variable
var tapTimer,
isTapHold = false;
$('#my_item_'+items[idx].user_item_id).bind('vmousedown vmouseup', function (event) {
if (event.type == 'vmousedown') {
//set the timer to run the `taphold` function in three seconds
//
tapTimer = setTimeout(function () {
isTapHold = true;
ShowMyItemInfo(items[idx]);
}, 3000);
} else {
//event.type == 'vmouseup'
//clear the timeout if it hasn't yet occured
clearTimeout(tapTimer);
//if the flag is set to false then this is a `tap` event
if (!isTapHold) {
//this is a tap, not a tap-hold
FitMyUpgradeItem(items[idx]);
}
//reset flag
isTapHold = false;
}
});
这样,事件将在用户按住手指三秒钟后触发。然后,只有在这三秒钟没有发生时,点击事件处理程序才会触发。只需在文档顶部或定义偶数之前的任何位置设置此项:
$.event.special.tap.emitTapOnTaphold = false;
然后你可以这样使用它:
for(var idx in items)
{
(function (idx) {
...
})(idx);
}
$('#button').on('tap',function(){
console.log('tap!');
}).on('taphold',function(){
console.log('taphold!');
});
就我个人而言,我认为这里的答案过于复杂了。如果您只想用一种简单的方法继续使用taphold事件,并忽略释放taphold时触发的click事件,下面是我在自己的项目中解决相同问题的方法:
// We will use this flag to ignore click events we don't want
var skipNextClick = false;
//Set up your event handler. You could do these using two handlers or one. I chose one.
$('div.element').on('click taphold', function (e) {
//set up a quick bool flag that is true if click
var isClick = (e.type == 'click');
if (isClick && !skipNextClick) {
//run your code for normal click events here...
}
else if (isClick && skipNextClick) {
//this is where skipped click events will end up...
//we need to reset our skipNextClick flag here,
//this way, our next click will not be ignored
skipNextClick = false;
}
else {
//taphold event
//to ignore the click event that fires when you release your taphold,
//we set the skipNextClick flag to true here.
skipNextClick = true;
//run your code for taphold events here...
}
});
我试过了,它似乎也在做同样的事情。:/iScroll对象中有这些项目。我不知道这是否会导致问题?好的,我在设备上尝试了JSFIDLE链接,但它无法正常工作。所有事件都会在android webview中触发。因此这是一个设备问题。我需要想出一种不同的设置这些事件的方法s、 …请再试一次JSFIDLE。我离开了点击,点击和vclick只是为了显示区别。js FIDLE在设备上仍然不起作用。目前,我不认为iScroll与这个问题有任何关系。好的,这很好。非常感谢。我现在唯一的问题是如何使这成为一个真正的点击和按住,而不是点击,按住,释放。我很抱歉I’我希望它能像taphold事件一样工作。因此,在大约750ms后,该功能被触发以完成taphold@jasonlg3d我添加了一个示例,说明如何使用超时来执行此操作,这样用户就不会抬起手指来获得反馈。请参阅我的答案的更新。在您之前,我一直在处理此问题。我在上面发布了我的解决方案。我必须这样做一些额外的东西,以确保iScroll仍然滚动,并且不会触发taphold事件。感谢您提供了完美的解决方案。我的windows 8手机只有一个问题。如果我“vmousedown”我的div,同时按下手指并移动它。然后当我松开手指时,不会触发“vmouseup”。这使得“ShowMyItemInfo”功能始终保持不变因为ClearTimeout没有运行,所以发生。尝试并测试了快速解决方案