How to know if browser tab is already open using Javascript?
Asked Answered
S

6

18

How to know or check if the two browser tab is already open and if those tab are open, the user will receive an alert box or msg box saying that 'the url is already open', something like that, in pure/native JavaScript? This browser tab is contain an external website which is I don't have any privileges to manipulate or change it. Thanks

Example URLs

yahoo.com and google.com

I want to alert the user if there's already open tab for yahoo.com and google.com

And I want to use tabCreate to open the url like this:

tabCreate("http://maps.google.com/", "tabMapsPermanentAddress");
mean to open a new tab, it is use in creating chrome extension
Smut answered 4/9, 2014 at 9:13 Comment(3)
window.open() return ref you can check before open window var windowObjectReference = window.open(strUrl, strWindowName[, strWindowFeatures]);Northamptonshire
like this jsfiddle.net/vyhy9wbu ? it will alert the user that url is already open?Smut
i think do you want to something like see this jsfiddle.net/vyhy9wbu/1Northamptonshire
J
12

You may use something like following

<!-- HTML -->
<a id="opener">Open window</a>

// JavaScript
var a = document.getElementById('opener'), w;        
a.onclick = function() {
  if (!w || w.closed) {
    w = window.open("https://www.google.com","_blank","menubar = 0, scrollbars = 0");
  } else {
    console.log('window is already opened');
  }
  w.focus();
};

Working jsBin | More on window.open method

If you want to control more than one window, use the snippet below

<!-- HTML -->
<a href="https://www.google.com" class="opener">Open google.com</a> | 
<a href="http://www.yahoo.com" class="opener">Open yahoo.com</a> 

//JavaScript
window.onload = function(){
  var a = document.querySelectorAll('.opener'), w = [], url, random, i;
  for(i = 0; i < a.length; i++){
    (function(i){
      a[i].onclick = function(e) {
        if (!w[i] || w[i].closed) {
          url = this.href;
          random = Math.floor((Math.random() * 100) + 1); 
          w[i] = window.open(url, "_blank", random, "menubar = 0, scrollbars = 0");
        } else {
          console.log('window ' + url + ' is already opened');
        }
        e.preventDefault();
        w[i].focus();
      };
    })(i);
  }
};

Working jsBin

If you don't want them to load in separated window, just exclude this line

random = Math.floor((Math.random()*100)+1);

and remove random reference from the next line

w[i] = window.open(url, "_blank", random, "menubar=0,scrollbars=0");

Side note: As you can see above, we created two windows with some third party content; you should know that there's no way to get any reference (to the parent/opener window) from them.

Jilt answered 4/9, 2014 at 10:8 Comment(13)
how can I combine your code with this code jsfiddle.net/jjjs5wd3/3 (courtesy of Casey Chu)Smut
I see. But if I have two URLs and I want to user give an alert that those URL are already open?Smut
Oh I see. Hope you can modify your code for two URLs :)Smut
@Smut The code for the first solution above was correct but I see, the w variable wasn't declared in that jsBin; now it works. In addition, I added another solution that allows you to control more than one window - you may have as much as you want. Let me know if it helped.Jilt
Is this correct jsbin.com/qozevegufaye/1 I try to modified your code using tabCreate @JiltSmut
What if the link will not click somewhere? I mean the url will just type in url box then if the user open another tab and go to same url, the user will give an alertSmut
@Smut Could you please add this tabCreate() function to your question because I have no clue what it does inside ;) Furthermore, no, there's no way to get notified if the user opens a window/link outside of your application. That thing is controlled by the browser itself; there's no way to ask browser like 'hey browser, let me know if the user opens a new window/tab/link from the address bar'- in other words, you can have kind of limited control only if the things happed inside your application...Jilt
@Smut ... Finally, using window.open method you're able to control when a window opens or if it has been closed; using plain anchor like <a href="url">go to this link</a> you'll be able to control when the window opens but you'll not know if it has been closed by the user - you can use cookies or locale storage to (eventually) get more control but it has sense only if the opened window has no third party content (like google.com, yahoo.com etc.)Jilt
i added the tabCreate() function in my question :)Smut
@Smut I see, it's related to chrome.tabs API. Well, this is something else and related to Chrome itself; let me check it first 'cause as far as I can see, it has some control over tabs inside the browser.Jilt
Yes, because I'm creating now a chrome extension for external websiteSmut
hi, please check my new question :)Smut
This is code to check exist tab browser and refresh it if (!w || w.closed) { // w = window w = window.open( route("yoururl"), '_blank' ); } else { console.log('window is already opened'); } w.focus(); w.location.href = route("yoururl");Volatilize
P
7

One basic idea is to store the tab count in either a cookie or localStorage, incrementing it on page load and decrementing it on page unload:

if (+localStorage.tabCount > 0)
    alert('Already open!');
else
    localStorage.tabCount = 0;

localStorage.tabCount = +localStorage.tabCount + 1;
window.onunload = function () {
    localStorage.tabCount = +localStorage.tabCount - 1;
};

Try opening this fiddle in multiple tabs.

Note that this technique is pretty fragile, though. For example, if for some reason the browser crashes, the unload handler won't run, and it'll go out of sync.

Pacification answered 5/9, 2014 at 4:25 Comment(6)
I see. Can you give me a live example with url's in your code?Smut
Like google.com, if this open it will alert using your code. Pls see the updated questionSmut
When the browser crashes the values in localStorege are preserved. The tabCount value will never reach 0 again.Transposal
This is also not reliable when the user is redirecting for login and coming back to the page.Craftsman
Page refresh increases the tab countJoanjoana
Tested on Safary /MacBook Air/ and it always alerted "Already open!". Also in Google sometimes with one browser tab is tabCount >1.Obstetrics
S
4

The answer by Casey Chu works fine until the browser crashes with the page open. On any next execution, the localStorage object will have initialized tabCount with non zero value. Therefore a better solution is to store the value in a session cookie. The session cookie will be removed when browser exits successfully. When the browser crashes the session cookie will actually be preserved but fortunately only for one next execution of the browser.

Object sessionStorage is distinct for each tab so it cannot be used for sharing tab count.

This is the improved solution using js-cookie library.

if (+Cookies.get('tabs') > 0)
    alert('Already open!');
else
    Cookies.set('tabs', 0);

Cookies.set('tabs', +Cookies.get('tabs') + 1);

window.onunload = function () {
        Cookies.set('tabs', +Cookies.get('tabs') - 1);
};
Sedgewake answered 13/5, 2016 at 12:8 Comment(1)
Instead of using cookies, you can also use BroadcastChannel.Seraphina
S
1

This answer: https://stackoverflow.com/a/28230846 is an alternative that doesn't require Cookies/js-cookie library. It better suited my needs. In a nutshell (see linked answer for full description):

$(window).on('storage', message_receive);

...

// use local storage for messaging. Set message in local storage and clear it right away
// This is a safe way how to communicate with other tabs while not leaving any traces
//
function message_broadcast(message)
{
    localStorage.setItem('message',JSON.stringify(message));
    localStorage.removeItem('message');
}


// receive message
//
function message_receive(ev)
{
    if (ev.originalEvent.key!='message') return; // ignore other keys
    var message=JSON.parse(ev.originalEvent.newValue);
    if (!message) return; // ignore empty msg or msg reset

    // here you act on messages.
    // you can send objects like { 'command': 'doit', 'data': 'abcd' }
    if (message.command == 'doit') alert(message.data);

    // etc.
}
Sg answered 8/6, 2018 at 14:23 Comment(0)
C
0

Just going to throw this up here, because I wish I had something like it. Make what you will of it.

If you want a solution for checking if you are the active tab that doesn't require a cookie, works as a React hook, and works whether or not the browser crashes, you can use this useIsActiveTab webhook which returns true if you are the most recent active tab/window. You can also set yourself as the active tab with activateTab.

import { useEffect, useState } from 'react';

const CHARACTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
const CHARACTERS_LENGTH = CHARACTERS.length;

function generateTabId() {
  let result = '';
  const prefix = 'TAB_';
  const length = 15;
  for (let i = 0; i < length - prefix.length; i++) {
    result += CHARACTERS.charAt(Math.floor(Math.random() * CHARACTERS_LENGTH));
  }
  if (prefix.includes('_')) {
    return `${prefix}${result}`;
  }
  return `${prefix}_${result}`;
};

const tabId = generateTabId();

export function activateTab(): void {
  localStorage.setItem('activeTab', tabId);
  const event = new Event('thisStorage');
  window.dispatchEvent(event);
}

export function useIsActiveTab(): boolean {
  const [isActiveTab, setIsActiveTab] = useState(false);
  useEffect(() => {
    setActiveTab();
    function updateIsActiveTab() {
      setIsActiveTab(checkIfActiveTab());
    }
    window.addEventListener('storage', updateIsActiveTab);
    window.addEventListener('thisStorage', updateIsActiveTab);
    updateIsActiveTab();
    return () => {
      window.removeEventListener('storage', updateIsActiveTab);
      window.removeEventListener('thisStorage', updateIsActiveTab);
    };
  }, []);
  return isActiveTab;
}

function checkIfActiveTab(): boolean {
  const activeTab = localStorage.getItem('activeTab');
  if (!activeTab) {
    console.error('localStorage.activeTab is not set');
    return true;
  }
  if (activeTab === tabId) {
    return true;
  }
  return false;
}

function setActiveTab(): void {
  localStorage.setItem('activeTab', tabId);
}
Canasta answered 3/2, 2021 at 6:20 Comment(0)
N
0
enter code here// Check if the 'tabs' session cookie exists
    if (!Cookies.get('tabs')) {
        Cookies.set('tabs', 0, { expires: 0 }); // Expires when the browser is closed
    }
    // Check if the session cookie exists and its value
    if (+Cookies.get('tabs') > 0) {
        `enter code here`alert('Already open!');
    } else {
        Cookies.set('tabs', 0, { expires: 1 }); // Expires after one day (adjust as needed)
    }
    // Increment the 'tabs' cookie value when opening a new tab
    Cookies.set('tabs', +Cookies.get('tabs') + 1);

    // Decrement the 'tabs' cookie value when closing a tab
    window.onunload = function () {
        Cookies.set('tabs', +Cookies.get('tabs') - 1);
    };

    // Decrement the 'tabs' cookie value when the tab is being closed
    window.addEventListener('beforeunload', function () {
        Cookies.set('tabs', +Cookies.get('tabs') - 1);
    });
Neotype answered 16/8, 2023 at 11:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.