touch events firing twice

泪湿孤枕 提交于 2019-11-29 14:08:25

问题


I am having problems on mobile devices/tablets with the events firing twice. When I click the following function, the menu that is supposed to drop down will drop down then immediataly slide back up. It is only an issue with touch devices.

$(document).on("touchend click", ".lines-button", function(e){

    e.stopImmediatePropagation();
    if($(this).hasClass("close")){
        $(this).removeClass("close");
        $(".widget1x1Back").next(".actionsHolder3").slideUp("fast", function() {
            $(this).remove();
        });             
    }else{

        var iconsList = $(this).closest(".top1x1").next(".hdnActnLst").find(".iconsHolder3").html();
        $(this).closest(".widget1x1").append(iconsList);
        $(this).closest(".widget1x1").find(".actionsHolder3").hide();
        $(this).closest(".widget1x1").find(".actionsHolder3").slideDown(700,"easeOutBack");
        $(this).addClass("close");
    }
});

Any input would be great, thanks!!


回答1:


Your issue is that your function is getting triggered twice (once for each event type). See the DEMO here (I used mousedown and click as I am on a desktop right now - but its the same principle).

You need to catch and handle duplicate calls to the event. You could try setting a handled boolean so the click event knows if the touch event handled the event or not (the touch event should be firing first). Something like this...

var handled = false;
$(document).on("touchend click", ".lines-button", function(e){
    e.stopImmediatePropagation();

    if(e.type == "touchend") {
        handled = true;
        handleIt();
    }
    else if(e.type == "click" && !handled) {
        handleIt();
    }
    else {
        handled = false;
    }
});

function handleIt() { 
        if($(this).hasClass("close")){
            $(this).removeClass("close");
            $(".widget1x1Back").next(".actionsHolder3").slideUp("fast", function() {
                $(this).remove();
            });             
        }else{

            var iconsList = $(this).closest(".top1x1").next(".hdnActnLst").find(".iconsHolder3").html();
            $(this).closest(".widget1x1").append(iconsList);
            $(this).closest(".widget1x1").find(".actionsHolder3").hide();
            $(this).closest(".widget1x1").find(".actionsHolder3").slideDown(700,"easeOutBack");
            $(this).addClass("close");  
        } 
}



回答2:


In most cases the following code will be ok:

$(document).on("touchend click", ".lines-button", function(e){
    if(e.type == 'touchend'){
        $(this).off('click');
    }
});

If touchend works, you may get rid of click.




回答3:


The following worked for me which is a slight modification for @JRules answer

// lo is just a global object holder 
let lo = {
    "handled":false
}

Using delegate because objects are not loaded on original page load

$('body').delegate('.linkRow','click touchend',function(e) {  //   
    e.stopPropagation();
    if(lo.handled === false){  // check
        doSomething()                 
        lo.handled = true
    }
    setTimeout(() => {  // now set to false later (example here is 1/2 sec)
        lo.handled = false
    }, 500)
});


来源:https://stackoverflow.com/questions/25165360/touch-events-firing-twice

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!