How to know if browser tab is already open using J

2020-02-08 04:17发布

问题:

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

回答1:

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.



回答2:

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.



回答3:

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


回答4:

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.
}