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>
