taphold事件后的jQuery调用点击事件 [英] jQuery calling click event after taphold event

查看:166
本文介绍了taphold事件后的jQuery调用点击事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Jquery和Jquery Mobile为Android开发一个PhoneGap应用程序。

I'm developing a PhoneGap app for Android using Jquery and Jquery Mobile.

我有一个需要两个事件绑定到每个项目的项目列表列表。我需要一个taphold事件和一个点击事件。我遇到的问题是当我做一个taphold,正确的taphold事件被触发。但是,一旦我释放,点击事件也被触发。如何防止点击事件在点击后触发?

I've got a list of items that need two events bound to each item in the list. I need a "taphold" event and a "click" event. The problem I'm having is when I do a "taphold", the correct "taphold" event is fired. However, as soon as I release, the click event is also fired. How can I prevent the click event from firing after a taphold?

代码:

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>');
        $('#my_item_'+items[idx].user_item_id).bind('taphold', {userItem:items[idx]},ShowMyItemInfo);
        $('#my_item_'+items[idx].user_item_id).bind('click tap', {userItem:items[idx]},FitMyUpgradeItem);
        console.log('UserItem '+items[idx].user_item_id+' loaded and events bound');
    }
    $('#my_items_loader').hide();
    myScroll.refresh();
}

在下面的建议之后,这是我结束了。这在iScroll对象中工作。

After the advice below, Here is what I ended up with. This works inside the iScroll object.

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();
}


推荐答案

$ c>点击和 taphold (我试图使用但遇到相同的问题,它似乎是一个固有的问题, taphold 事件),您可以使用 vmousedown 并设置一个标志,然后绑定到 vmouseup 以确定它是点击还是 taphold

Rather than use tap and taphold (which I've tried to use but ran into the same problems, it seems to be an inherent issue with the taphold event) you can use vmousedown and set a flag, then bind to vmouseup to determine if it was a tap or a taphold:

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, code> ShowMyItemInfo(items [idx]); 工作时不引用更改循环的每次迭代的变量。一个容易创建IIFE的方法是使用 $。each()。否则你的循环看起来像这样:

For this to work properly you'll have to add an IIFE around the loop-code or change ShowMyItemInfo(items[idx]); to work without referencing the variable that changes each iteration of the loop. An easy to create an IIFE is to just use $.each(). Otherwise your loop would look something like this:

for(var idx in items)
{
    (function (idx) {
        ...
    })(idx);
}

IIFE = Immediately-Invoked-函数表达式。它允许我们对我们传入IIFE的变量的当前状态进行快照。因此,当我们传递 idx (技术上,第二个实例是传递的变量,第一个实例是IIFE中可用的变量,为了简单起见, ids_new ),当 tap 事件处理程序触发时,传入的值被保存。

IIFE = Immediately-Invoked-Function-Expression. It allows us to take a "snapshot" of the current state of variables we pass into the IIFE. So as we pass in idx (technically the second instance is the variable that's being passed in, and the first instance is the variable available inside the IIFE, which could be changed to something like ids_new for simplicity sake), the value passed in is saved for when the tap event handler fires.

您还可以设置超时以确定 taphold 而不是使用 vmouseup 事件:

You can also set a timeout to determine taphold rather than using the vmouseup event:

//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;
    }
});

这样,用户按住手指三秒钟后,事件将触发。然后点击事件处理程序只有在三秒没有发生时才会触发。

This way the event will fire after the user holds down their finger for three seconds. Then the tap event handler will only fire if that three seconds did not occur.

这篇关于taphold事件后的jQuery调用点击事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆