jQuery在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

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

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

代码:

函数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没有运行,所以发生。尝试并测试了快速解决方案