0

I have now tried to find a solution for this problem for a couple of hours now and apparently I can't solve this problem myself.

So the idea itself is quite simple. I want to trigger a click for #game-undo and it works just fine for desktop. But the code below will result in ghost clicks when it comes to mobile and tablets.

$(document).on('click tap touchstart','.game-undo-btn',function(event){
    $('#game-undo').trigger('click');
});

So the first solution I tried was the following:

$(document).on('click tap touchstart','.game-undo-btn',function(event){
    if(event.type == "click") {
        $('#game-undo').trigger('click');
        console.log('click triggered');
    } 
    else if(event.type == "tap") {
        $('#game-undo').trigger('click');
        console.log('tap triggered');
    } 
    else if(event.type == "touchstart") {
        $('#game-undo').trigger('click');
        console.log('touchstart triggered');
    }
});

My logic from PHP tells me that if the event.type is click then the rest of the else statements wont be executed. I guess I'm wrong because the console tells me that both click and touchstart is triggered.

I then tried to play around with event.preventDefault(); but I quickly found out that this was not possible because when touchstart is added - the event listener will be treated as passive.

The message in the console for using event.preventDefault(); is:

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive.

Okay - so the next step for me was to play around with event.stopPropagation(); - but this is ignored and the else statements will be executed anyway.

There is no duplicate code.

I hope you guys can help me out. Thank you.

Niels Hermann
  • 611
  • 2
  • 6
  • 13
  • 1
    First idea that comes to my mind is to debounce it. – Flewz Jan 13 '23 at 12:48
  • @Flewz - Thank you for that suggestion. I have not tried that before - so I don't know how to do it, but I will look into it. – Niels Hermann Jan 13 '23 at 12:50
  • @Flewz - Do you have any advice on where to start? I have now searched for quite a while, and even though I do get the logic, there is not much info about how to do it in jQuery. I would like to do it without a plugin since my website is "heavy enough" as it is. So if you have an idea I will appreciate it. – Niels Hermann Jan 13 '23 at 13:36
  • The prevent default message is from chrome. [The javascript answer is to add the touchstart event listener with the paramater: passive: false;](https://github.com/inuyaksa/jquery.nicescroll/issues/799#issuecomment-522275951) [Jquery doesn't let you pass parameters so you can use this fix instead.](https://stackoverflow.com/a/62177358/3585500) – ourmandave Jan 13 '23 at 14:57
  • [Same question from 2011 here with a bunch of answers.](https://stackoverflow.com/questions/7018919/how-to-bind-touchstart-and-click-events-but-not-respond-to-both) (Sort by modified date to get recent answers.) – ourmandave Jan 13 '23 at 15:13

1 Answers1

1

To implement debounce in JS does not require a plugin. Bellow are 2 examples.

function debounce(func, timeout = 100){
    let timer;
    // args are your func arguments
    return (...args) => {
        clearTimeout(timeout);

        timer = setTimeout(() => {
            func.apply(this, args);
        }, timeout);
    };
}

function _event_handler(event){
    // your event handler code
}

const event_handler = debounce(() => _event_handler);

$(document).on('click tap touchstart', '.game-undo-btn', event_handler);
// jquery comes with it

function _event_handler(event){
    // your event handler code
}

// timeout, function
const event_handler = $.debounce(300, _event_handler);
Flewz
  • 343
  • 9