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
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)
});
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
.
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");
}
}