On the page you want to detect is open

  //-------------------------------------------------------------------
  //----- PAGE PING - RECEVIE PINGS FROM PAGE OPEN IN ANOTHER TAB -----
  //-------------------------------------------------------------------
  //(There is seperate code that pings us on another page)
  <script>
    function PagePingStartFocusReceiver()
    {
      const ChannelName='SiteTabCoord';
      const SupportsBC=!!window.BroadcastChannel;
      const BC=SupportsBC ? new BroadcastChannel(ChannelName) : null;
      const FallbackKey='tabcoord_msg';

      function Send(payload)
      {
        const msg={...payload, ts:Date.now()};
        if(BC)
        {
          BC.postMessage(msg);
        }
        else
        {
          localStorage.setItem(FallbackKey, JSON.stringify(msg));
          localStorage.removeItem(FallbackKey);
        }
      }

      function OnMessageLike(data)
      {
        if(!data || typeof data!=='object') return;

        if(data.type==='ping')
        {
          //Tell the closing tab that we exist and share our URL
          Send({type:'here', url:location.href});
        }
        else if(data.type==='please-focus')
        {
          try { window.focus(); } catch(_) {}
          //Optional: visual cue
          //document.title='● '+document.title;
          //setTimeout(()=>document.title=document.title.replace(/^●\s*/,''), 2000);
        }
      }

      if(BC)
      {
        BC.onmessage=(e)=>OnMessageLike(e.data);
      }
      else
      {
        window.addEventListener('storage', function(e)
        {
          if(e.key===FallbackKey && e.newValue)
          {
            try { OnMessageLike(JSON.parse(e.newValue)); } catch(_) {}
          }
        });
      }
    }
    //Run on load
    document.addEventListener('DOMContentLoaded', PagePingStartFocusReceiver);
  </script>

On the page you want to find out if the other page is open

//-------------------------------------------------------------------------------
//----- PAGE PING - DETECT IF A PAGE IS ALREADY OPEN IN ANOTHER BROWSER TAB -----
//-------------------------------------------------------------------------------
//(There is separate code that we ping on the other page)
$HtmlOutput .= <<<_END
  <script>
    function PagePingStartClosingTab()
    {
      const ChannelName='SiteTabCoord';
      const TabId=(self.crypto && crypto.randomUUID) ? crypto.randomUUID() : Math.random().toString(36).slice(2);
      const SupportsBC=!!window.BroadcastChannel;
      const BC=SupportsBC ? new BroadcastChannel(ChannelName) : null;
      const FallbackKey='tabcoord_msg';
      const TimeoutMs=5000;
      const PingCount=6;
      const PingInterval=250;

      let GotReply=false;
      let OtherUrl=null;
      let DoneCloseAction=false;

      function Send(payload)
      {
        const msg={...payload, sender:TabId, ts:Date.now()};
        if(BC)
        {
          BC.postMessage(msg);
        }
        else
        {
          localStorage.setItem(FallbackKey, JSON.stringify(msg));
          localStorage.removeItem(FallbackKey);
        }
      }

      function OnMessageLike(data)
      {
        if(!data || typeof data!=='object') return;
        if(data.sender===TabId) return;

        if(data.type==='here')
        {
          GotReply=true;
          OtherUrl=data.url || null;
          Proceed();
        }
        //We ignore 'ping' here; this tab is the closer
      }

      function Proceed()
      {
        if(!GotReply) 
          return;

        //----- ANOTHER TAB IS OPEN -----

        //Ask the other tab to try focusing itself (browser may ignore)
        Send({type:'please-focus'});

        //If this tab was opened via window.open by script, we can usually close it
        if(window.opener && !window.opener.closed)
        {
          try { window.close(); return; } catch(_) {}
        }

        //We couldn't close, so inform the user
        if (DoneCloseAction)
          return;
        DoneCloseAction = true;
        
        //----- WE COULDN'T CLOSE THE PAGE - DO SOMETHING TO TELL USER HERE? -----
        //alert('A similar page is already open in another browser tab. Please use that tab to continue.' + (OtherUrl ? 'URL: ' + OtherUrl : ''));

        //<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


      }

      if(BC)
      {
        BC.onmessage=(e)=>OnMessageLike(e.data);
      }
      else
      {
        window.addEventListener('storage', function(e)
        {
          if(e.key===FallbackKey && e.newValue)
          {
            try { OnMessageLike(JSON.parse(e.newValue)); } catch(_) {}
          }
        });
      }

      //Burst of pings to find the focus tab
      for(let i=0;i<PingCount;i++)
      {
        setTimeout(()=>Send({type:'ping'}), i*PingInterval);
      }

      //Give it time to answer; then proceed if we got a reply
      setTimeout(function()
      {
        Proceed();
      }, TimeoutMs);
    }
    //Run on load
    document.addEventListener('DOMContentLoaded', PagePingStartClosingTab);
  </script>
USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through resources like this. We hope you find it helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support here. If you need help with a problem please use one of the many online forums.

Comments

Your email address will not be published. Required fields are marked *