在taphold事件之后jQuery调用click事件

我正在使用 JqueryJquery Mobile为 Android开发PhoneGap应用程序.

我有一个项目列表,需要两个事件绑定到列表中的每个项目.我需要一个“taphold”活动和一个“点击”活动.我遇到的问题是当我做“taphold”时,正确的“taphold”事件被解雇了.但是,一旦我发布,click事件也会被触发.如何防止点击事件在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',FitMyUpgradeItem);
        console.log('UserItem '+items[idx].user_item_id+' loaded and events bound');
    }
    $('#my_items_loader').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();
}

解决方法

而不是使用tap和taphold(我试图使用但遇到同样的问题,似乎是taphold事件的固有问题)你可以使用vmousedown并设置一个标志,然后绑定到vmouseup以确定它是否是一个水龙头或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或更改ShowMyItemInfo(items [idx]);在不引用改变循环的每次迭代的变量的情况下工作.一个易于创建IIFE的方法就是使用$.each().否则你的循环看起来像这样:

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

IIFE =立即调用函数表达式.它允许我们对我们传递到IIFE的变量的当前状态进行“快照”.因此,当我们传入idx时(从技术上讲,第二个实例是传入的变量,第一个实例是IIFE中可用的变量,为简单起见,可以将其更改为类似ids_new),传入的值将被保存当tap事件处理程序触发时.

更新

您还可以设置超时以确定taphold而不是使用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;
    }
});

这样,在用户按下手指三秒钟后,事件将触发.然后,如果没有发生三秒钟,则只会触发点击事件处理程序.

相关文章

jQuery插件的种类 1、封装对象方法 这种插件是将对象方法封装起来,用于对通过选择器获取的jQuery对象进...
扩展jQuery插件和方法的作用是非常强大的,它可以节省大量开发时间。 入门 编写一个jQuery插件开始于给...
最近项目中需要实现3D图片层叠旋转木马切换的效果,于是用到了jquery.roundabout.js。 兼容性如图: ht...
一、什么是deferred对象? 开发网站的过程中,我们经常遇到某些耗时很长的javascript操作。其中,既有异...
AMD 模块 AMD(异步模块定义,Asynchronous Module Definition)格式总体的目标是为现在的开发者提供一...