如何知道浏览器选项卡是不是已经使用 Javascript 打开?
Posted
技术标签:
【中文标题】如何知道浏览器选项卡是不是已经使用 Javascript 打开?【英文标题】:How to know if browser tab is already open using Javascript?如何知道浏览器选项卡是否已经使用 Javascript 打开? 【发布时间】:2014-10-28 23:17:57 【问题描述】:如何知道或检查两个浏览器选项卡是否已打开,如果这些选项卡已打开,用户将收到一个警告框或消息框,提示“网址已打开”,类似这样的纯/原生 javascript?此浏览器选项卡包含一个外部网站,我没有任何权限来操作或更改它。谢谢
示例网址
yahoo.com and google.com
如果 yahoo.com 和 google.com 已经打开标签页,我想提醒用户
我想使用 tabCreate 像这样打开网址:
tabCreate("http://maps.google.com/", "tabMapsPermanentAddress");
mean to open a new tab, it is use in creating chrome extension
【问题讨论】:
window.open()
return ref
可以在打开窗口前查看var windowObjectReference = window.open(strUrl, strWindowName[, strWindowFeatures]);
喜欢这个jsfiddle.net/vyhy9wbu ?它会提醒用户 url 已经打开?
我想你想看看这个jsfiddle.net/vyhy9wbu/1
【参考方案1】:
只是要把它扔在这里,因为我希望我有类似的东西。随心所欲。
如果你想要一个解决方案来检查你是否是不需要 cookie 的活动选项卡,作为 React 钩子工作,并且无论浏览器是否崩溃都可以工作,你可以使用这个 useIsActiveTab
webhook,它返回 true如果您是最近的活动选项卡/窗口。您还可以使用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);
【讨论】:
【参考方案2】:这个答案:https://***.com/a/28230846 是不需要 Cookies/js-cookie 库的替代方案。它更适合我的需要。简而言之(有关完整说明,请参阅链接答案):
$(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.
【讨论】:
【参考方案3】:answer by Casey Chu 工作正常,直到浏览器在页面打开时崩溃。在任何下一次执行中,localStorage
对象将使用非零值初始化 tabCount
。因此,更好的解决方案是将值存储在会话 cookie 中。当浏览器成功退出时,会话 cookie 将被删除。当浏览器崩溃时,会话 cookie 实际上会被保留,但幸运的是仅用于浏览器的下一次执行。
对象 sessionStorage
对于每个选项卡都是不同的,因此它不能用于共享选项卡计数。
这是使用js-cookie 库的改进解决方案。
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);
;
【讨论】:
不使用cookies,也可以使用BroadcastChannel。【参考方案4】:你可以使用类似下面的东西
<!-- 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
如果要控制多个窗口,使用下面的sn-p
<!-- 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
如果您不希望它们在单独的窗口中加载,只需排除此行
random = Math.floor((Math.random()*100)+1);
并从下一行删除random
引用
w[i] = window.open(url, "_blank", random, "menubar=0,scrollbars=0");
旁注:正如您在上面看到的,我们创建了两个包含一些第三方内容的窗口;你应该知道没有办法从他们那里获得任何参考(对父/打开器窗口)。
【讨论】:
我怎样才能把你的代码和这个代码结合起来jsfiddle.net/jjjs5wd3/3(由Casey Chu提供) 我明白了。但是,如果我有两个 URL,并且我想提醒用户这些 URL 已经打开? 哦,我明白了。希望您可以修改两个 URL 的代码:) @User014019 上面第一个解决方案的代码是正确的,但我知道,w
变量没有在那个 jsBin 中声明;现在它可以工作了。此外,我添加了另一种解决方案,允许您控制多个窗口 - 您可以拥有任意数量的窗口。如果有帮助,请告诉我。
这是检查现有标签浏览器并刷新它的代码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");
【参考方案5】:
一个基本的想法是将标签计数存储在 cookie 或 localStorage
中,在页面加载时递增,在页面卸载时递减:
if (+localStorage.tabCount > 0)
alert('Already open!');
else
localStorage.tabCount = 0;
localStorage.tabCount = +localStorage.tabCount + 1;
window.onunload = function ()
localStorage.tabCount = +localStorage.tabCount - 1;
;
在多个标签中尝试opening this fiddle。
但请注意,这种技术非常脆弱。例如,如果由于某种原因浏览器崩溃,卸载处理程序将不会运行,并且会不同步。
【讨论】:
我明白了。你能给我一个在你的代码中包含 url 的活生生的例子吗? 像 google.com 一样,如果打开它,它将使用您的代码发出警报。请查看更新后的问题 当浏览器崩溃时,localStorege
中的值会被保留。 tabCount
值将永远不会再达到 0。
这在用户重定向登录并返回页面时也不可靠。
页面刷新增加标签数以上是关于如何知道浏览器选项卡是不是已经使用 Javascript 打开?的主要内容,如果未能解决你的问题,请参考以下文章
当用户选择“在新选项卡中打开”/“在新窗口中打开”而不是使用 html/javascript 点击时如何到达所需的页面
如何添加 favicon 以响应应用程序浏览器选项卡(重复)
浏览器如何暂停/更改JavaScript时选项卡或窗口未激活?