2

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.

  • What are you trying to accomplish with this? – Herohtar Feb 20 '18 at 22:26
  • where is it failling? how do you know it fails 9.5 times out of 10? maybe you are not clicking under that 250 ms window – miguelglz Feb 20 '18 at 22:31
  • @miguelglz If I set window.stop() on 1ms loop on a random page in console, it still fails 9.5/10 times –  Feb 20 '18 at 22:33
  • does it works with 1000 ms? – miguelglz Feb 20 '18 at 22:36
  • `window.stop()` is not the way to do this. That is the same as clicking the stop button in your browser. It is unreliable because the new page is occasionally loading very quickly before your 250ms timeout. – Herohtar Feb 20 '18 at 22:39
  • Why not use a check within a single click event (like is ctrl+shift being held) and preventDefault only in that case? – Patrick Evans Feb 20 '18 at 22:39
  • @Herohtar Yeah! It have become very unreliable now even for personal use. Earlier things used to load slow and now processors are much faster. It is just for a personal project. –  Feb 20 '18 at 22:42

2 Answers2

1

I think you're looking for the dblclick javascript event. It's usable on all updated browsers currently.

There's already a post here: Detect if browser/device supports double click events to detect if it's supported by using a timeout to check if there is an another click after the first click.

Bastien Robert
  • 809
  • 1
  • 10
  • 31
  • But I cannot prevent single click redirect there –  Feb 20 '18 at 22:24
  • Check the answer I linked (https://stackoverflow.com/a/14353886/7355534), just add a `preventDefault()` on the first click condition before the `setTimeout `, and add your event function if there's only one click, or two, in the conditions inside the `setTimeout ` – Bastien Robert Feb 20 '18 at 22:27
  • I don't want to use `preventDefault` as I mentioned –  Feb 20 '18 at 22:33
  • 1
    The only alternatives to `preventDefault()` method are `stopPropogation()` and `return false`. Check this to see more https://stackoverflow.com/questions/18971284/event-preventdefault-vs-return-false-no-jquery – Bastien Robert Feb 20 '18 at 22:39
  • 1
    But they are same thing. I don't want to cancel event in first place :) –  Feb 20 '18 at 23:06
  • Oww... And I suppose it has to be targeted on a link ? – Bastien Robert Feb 20 '18 at 23:11
  • It can be any anchor tag on the internet. –  Feb 20 '18 at 23:12
  • But this (https://stackoverflow.com/a/14353886/7355534) still doesn’t work if you set the first event and the second event without any preventDefault ? – Bastien Robert Feb 20 '18 at 23:15
0

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