Search code examples
javascripthtmlgreasemonkeytampermonkey

Prevent default single click event on double click on a link in HTML


My code is pretty simple:

var clickCount = 0, clickEl = [];
var manualClick = false;
$(document).on('click', 'a', function (e) {
    if (e.altKey || e.ctrlKey || e.shiftKey) {
        return;
    }
    clickCount = clickCount + 1;
    clickEl[clickCount] = this;

    var that = this;
    if (1 === clickCount) {
        setTimeout(function () {
            if (2 === clickCount && clickEl[1] === clickEl[2]) {
                window.stop();
                embed_anchor(that);
            }
            clickCount = 0;
        }, 250);
    }
});

It basically checks if there is double click. If yes, it cancel the single click redirect using window.stop(). It used to work great, but I don't know if it's Chrome or my new PC, window.stop() failing 9.5/10 times.

Even a simple code like:

setInterval(function () {
    window.stop();
}, 1);

is not able to prevent redirect these days. Is there any alternative solution for me. I ideally don't want to use e.preventDefault() because this script is part of TamperMonkey and I feel e.preventDefault() will break single click on ton of sites.

Is there any way to hold the event for 250 ms, or cancel and raise the same event (It must behave like last one so no issues with any site). I am open too pretty much everything. I would prefer if my script don't work on some sites rather than breaking any site.


Solution

  • Here is the piece of code I wrote to solve my problem:

    $.fn.on2 = function(type, sel, handler) {
        this[0].addEventListener(type, function(event) {
            var t = event.target;
            while (t && t !== this) {
                if (t.matches(sel)) {
                    handler.call(t, $.event.fix(event));
                }
                t = t.parentNode;
            }
        }, true);
    }
    
    var clickEvents = [];
    $(document).on2('click', 'a', function (event) {
        if (event.altKey || event.ctrlKey || event.shiftKey || this.text.length == 0) {
            return;
        }
        clickEvents.push(event);
    
        if (event.originalEvent.isTrusted) {
            event.preventDefault();
            event.stopImmediatePropagation();
        }
    
        var target = this;
        if (1 === clickEvents.length) {
            setTimeout(function () {
                if (2 === clickEvents.length && clickEvents[0].target == clickEvents[1].target) {
                    doWhatever(clickEvents[0].target);
                } else {
                    clickEvents[clickEvents.length-1].target.dispatchEvent(new MouseEvent("click", clickEvents[clickEvents.length-1].originalEvent));
                }
                clickEvents = [];
            }, 250);
        }
    });