3

Opening a JavaScript-based link in a new window/tab.

I have a link

<a href='/page' onclick='trackClick()'>Page</a>

What I believe is happening here is that the trackClick() function may not have enough time to execute before browser redirects to a new page. (BTW: Am I wrong here?)

To workaround that, I have changed the html to

<a href='#' onclick='trackClick('/page')'>Page</a>

where trackClick function would redirect to a next page after it has sent a signal to analytics endpoint to avoid racing condition.

As a result, "shift+click" or "right+click open in a new window" now will not open the the /page in a new window/tab.

What's the best way to overcome this? How likely for the browser to not wait for the onclick event to finish before redirecting to a next page?

thank you

Oleksandr
  • 283
  • 1
  • 4
  • 15

1 Answers1

3

The short answer is, onclick != right click.

For a quick and dirty demo

<script>
  function leftClick() {
    alert("click");
  }

  function rightClick() {
    alert("right click");
  }

  function mouseDown() {
    alert("Mouse down");
  }

  function mouseUp() {
    alert("Mouse up");
  }
</script>
<a href="http://www.google.com" onclick="leftClick()">CLick Me</a><br>
<a href="http://www.google.com" oncontextmenu="rightClick()">Right CLick Me</a><br>
<a href="http://www.google.com" onmousedown="mouseDown()">Any Click Me</a><br>
<a href="http://www.google.com" onmouseup="mouseUp()">Any Click Me</a><br>

So what you actually want is:

<a href='/page' onclick='trackClick()' oncontextmenu="trackClick()">Page</a>

Or maybe

<a href='/page' onmouseup='trackClick()' >Page</a> 

Better sill look at using unobtrusive handlers and the mousedown and mouseup events

How likely for the browser to not wait for the onclick event to finish before redirecting to a next page?

The onclick will complete. If you were to return false from a click handler the navigation will not occur at all. Demo

Jon P
  • 19,442
  • 8
  • 49
  • 72
  • 1
    arguably, contextmenu is not right click either... You can very well trigger a contextmenu from an other input (some keyboards have a contextmenu key). Right click would be mousedown=>e.buttons===2 **+** mouseup=>e.buttons===2 – Kaiido Jul 18 '18 at 02:24
  • @Kaiido, you are correct, I was trying to keep it simple, perhaps I've over simplified it. – Jon P Jul 18 '18 at 02:35
  • Well the real problem is that your code won't track page opening per se, and if user opens the contextmenu multiple times, without ever clicking "open in new tab/window", you'll have tracked false positives. (same for mouseup, + if you don't check that mousedown was also made on the same element, you'll also track false clicks) – Kaiido Jul 18 '18 at 02:48
  • Yeah, we know nothing about `trackClick()` it could be attempting to trace the element clicked on a page to cause a navigation event, not the target page load. – Jon P Jul 18 '18 at 02:54
  • In that case setting the `href` directly to the correct value would be the correct solution. – Kaiido Jul 18 '18 at 02:55
  • Thanks guys. The trackClick function should capture the fact that user has clicked on a link (no matter is it a new tab/window or shift+click or just a normal click) and send a signal to Google Analytics. This is the one which gets me worried. What if browser redirects to a new page faster than analytics library would send a signal to GA... – Oleksandr Jul 18 '18 at 03:45
  • @Oleksandr - I'm a bit late to the game but I thought I'd mention the "beacon" API in case you weren't already aware of it. https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API/Using_the_Beacon_API which is useful because "Beacon requests are guaranteed to be initiated before the page unloads" and that should address your concern. Google Analytics can use this API if you instruct it to, see the section "Specifying different transport mechanisms" in https://developers.google.com/analytics/devguides/collection/analyticsjs/sending-hits – Dan Roberts Jul 09 '19 at 10:28