How to detect multiple window usage in JS

Athos

2009-03-01 00:15:26
Opened: 2529 times

When designing a web application, one should keep tabbed browsing in mind, because this is one of the greatest features in browser-history. So great that even Microsoft had to implement it in IE!

But sometimes using an application in multiple windows or tabs just doesn't make much sense, and can be expensive. For example a chat or IM application (like Meebo) polls the server nearly in every seconds, and doing that simultaneously in more tabs or windows is simply wasting resources on both server and client side. In such situations a script to detect multiple window usage and notify the user can come handy. Let's see, how to do that.

Detecting multiple windows doesn't seem to be easy. From server-side, it's impossible. XSRF (or CSRF) tokens can be used to detect if a form has been downloaded from the server before it was sent back filled with data, and if we limit the number of acceptable tokens to 1, we can be sure that when the user opens our page in a new tab, a form post from the old one won't be accepted. (And this way we also break usage of navigation buttons of the browser.)

The problem also seems to be unsolvable from client-side. We can detect only that case trivially, when our script is the opener of the new window (window.open()) - of course. But there's no event-handler or callback function to notify our script running in an already opened tab when the user opens a new window, types our URL and hits enter.

The trick is a well-known object: window. In JavaScript, every global object (functions, variables) will be a property of the window object. This object represents the window (tab, content-window of an iframe) itself our script is running in. We can change it's location property (location.href to be precise) to navigate the user to another URL, access it's navigator property to get some information about the browser, etc. The window object has some properties that rarely or never change, one of them is name. This property only changes when a script changes it. Once it's set, it remains even if the user navigates to a completely different site!

This behavior can be extremely useful when it comes to statistics and analytics, and also when we want to know how many tabs do our visitors open to use our application.

When the user opens our site the first time, window.name won't be set, and no cookies will be assigned to our domain. We pick a unique identifier which will be assigned to window.name and stored in a cookie. Next time our site is loaded, we can compare our cookie and window.name, and if it differs, that means our user is using a new window. To avoid false positives, we have to clear the cookie when the user navigates away from our site or closes the last tab. We can use window.onunload or window.onbeforeunload events to do that.

I made a very simple demonstration, which works in all major browsers (FF, IE7, Safari, Opera), and the over-commented source code is also available.

Tags: web php javascript window name

Comments (3)

Ceriak Ceriak
2009-03-03 00:09:27

Nice one, though I would be rather indignant facing such a message. I open nearly all links in new tabs – and I don’t want any application to force me to change my browsing behaviours. Use with extreme foresight!

Nigel Nigel
2010-07-13 21:07:27

This is great! Thank you. It solves a problem for a web app I'm working on (linked above). One question: Why do you need the detectNewWindowLoop() function running periodically? Won't each new window/tab check for an existing one when it is opened?

Athos Athos
2010-07-14 20:53:18

@Nigel: Thank you for your comment! The loop is used to detect a second window of the application in the first one so not just the new window knows he's a duplicate, but the older one will detect that a second window has been opened (that might have messed things up on both client and server side). But it was buggy a bit, the conditions in the init() function were inconsistent. Now it's fixed. The idea is that the cookie on the client side named jsToken can be used to communicate between windows. detectNewWindowLoop() checks this cookie and when it gets changed, that means that a second window somewhere messed it up.

Your comment

Some HTML tags are allowed:

<a href="http://www.example.com">link</a>, <blockquote></blockquote>, <center></center>, <code></code>, <del></del>, <em></em>, <img src="http://www.example.com/picture.jpg" alt="Alternate text" />, <small></small>, <pre></pre>, <strong></strong>, <sub></sub>, <sup></sup>