我想用 JavaScript 检查用户是否已经在其浏览器的另一个选项卡中打开了我的网站。
看来我无法做到具有页面可见性
…
我看到的唯一方法是使用基于会话cookie的WebSocket,并检查客户端是否具有多个套接字。但是通过这种方式,我必须从当前选项卡中询问服务器,该用户是否在其当前浏览器选项卡旁边打开了一个选项卡。这有点牵强!
也许与localstorage
?
使用本地存储,我创建了一个简单的演示,该演示应可以完成您的工作。基本上,它只是维护当前打开的窗口的数量。当窗口关闭时,将触发卸载事件,并将其从总窗口数中删除。
当您初看它时,您可能会认为发生的事情比实际更多。多数是为了将逻辑添加到谁是“主”窗口中,以及在关闭孩子时谁应该接管“主”窗口中的尝试。(因此,setTimeout调用以重新检查是否应将其提升到主窗口)
在抓了一些头之后,我认为实现起来将花费太多时间,并且超出了此问题的范围。
但是,如果您打开两个窗口(“主窗口”和“子窗口”)并关闭了“主窗口”,则该子窗口将升级为主窗口。
在大多数情况下,您应该能够大致了解发生的事情并将其用于自己的实现中。
哦,是的,实际上可以看到它的作用…在多个窗口中打开链接。:)
我已经进行了必要的更改,以使本地存储维护“主”窗口。关闭选项卡后,子窗口便可以升级为主窗口。有两种方法可以通过传递给WindowStateManager的构造函数的参数来控制“主”窗口状态。这个实现比我以前的尝试要好得多。
JavaScript:
// noprotect
var statusWindow = document.getElementById('status');
(function (win)
{
//Private variables
var _LOCALSTORAGE_KEY = 'WINDOW_VALIDATION';
var RECHECK_WINDOW_DELAY_MS = 100;
var _initialized = false;
var _isMainWindow = false;
var _unloaded = false;
var _windowArray;
var _windowId;
var _isNewWindowPromotedToMain = false;
var _onWindowUpdated;
function WindowStateManager(isNewWindowPromotedToMain, onWindowUpdated)
{
//this.resetWindows();
_onWindowUpdated = onWindowUpdated;
_isNewWindowPromotedToMain = isNewWindowPromotedToMain;
_windowId = Date.now().toString();
bindUnload();
determineWindowState.call(this);
_initialized = true;
_onWindowUpdated.call(this);
}
//Determine the state of the window
//If its a main or child window
function determineWindowState()
{
var self = this;
var _previousState = _isMainWindow;
_windowArray = localStorage.getItem(_LOCALSTORAGE_KEY);
if (_windowArray === null || _windowArray === "NaN")
{
_windowArray = [];
}
else
{
_windowArray = JSON.parse(_windowArray);
}
if (_initialized)
{
//Determine if this window should be promoted
if (_windowArray.length <= 1 ||
(_isNewWindowPromotedToMain ? _windowArray[_windowArray.length - 1] : _windowArray[0]) === _windowId)
{
_isMainWindow = true;
}
else
{
_isMainWindow = false;
}
}
else
{
if (_windowArray.length === 0)
{
_isMainWindow = true;
_windowArray[0] = _windowId;
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
else
{
_isMainWindow = false;
_windowArray.push(_windowId);
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(_windowArray));
}
}
//If the window state has been updated invoke callback
if (_previousState !== _isMainWindow)
{
_onWindowUpdated.call(this);
}
//Perform a recheck of the window on a delay
setTimeout(function()
{
determineWindowState.call(self);
}, RECHECK_WINDOW_DELAY_MS);
}
//Remove the window from the global count
function removeWindow()
{
var __windowArray = JSON.parse(localStorage.getItem(_LOCALSTORAGE_KEY));
for (var i = 0, length = __windowArray.length; i < length; i++)
{
if (__windowArray[i] === _windowId)
{
__windowArray.splice(i, 1);
break;
}
}
//Update the local storage with the new array
localStorage.setItem(_LOCALSTORAGE_KEY, JSON.stringify(__windowArray));
}
//Bind unloading events
function bindUnload()
{
win.addEventListener('beforeunload', function ()
{
if (!_unloaded)
{
removeWindow();
}
});
win.addEventListener('unload', function ()
{
if (!_unloaded)
{
removeWindow();
}
});
}
WindowStateManager.prototype.isMainWindow = function ()
{
return _isMainWindow;
};
WindowStateManager.prototype.resetWindows = function ()
{
localStorage.removeItem(_LOCALSTORAGE_KEY);
};
win.WindowStateManager = WindowStateManager;
})(window);
var WindowStateManager = new WindowStateManager(false, windowUpdated);
function windowUpdated()
{
//"this" is a reference to the WindowStateManager
statusWindow.className = (this.isMainWindow() ? 'main' : 'child');
}
//Resets the count in case something goes wrong in code
//WindowStateManager.resetWindows()
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id='status'>
<span class='mainWindow'>Main Window</span>
<span class='childWindow'>Child Window</span>
</div>
</body>
</html>
CSS:
#status
{
display:table;
width:100%;
height:500px;
border:1px solid black;
}
span
{
vertical-align:middle;
text-align:center;
margin:0 auto;
font-size:50px;
font-family:arial;
color:#ba3fa3;
display:none;
}
#status.main .mainWindow,
#status.child .childWindow
{
display:table-cell;
}
.mainWindow
{
background-color:#22d86e;
}
.childWindow
{
background-color:#70aeff;
}
问题内容: 任何人都知道是否可以使用PHP检查网站是否在iframe中。 我知道使用javascript是可能的,但是我找不到使用PHP的任何示例? 问题答案: PHP永远不在iframe中。PHP在服务器端执行,并生成HTML,Javascript或文本之类的输出。PHP生成的输出可能会产生或驻留在iframe中,但PHP本身不会。 更多细节 关于您在注释中添加的其他详细信息(您希望在直接向站点
这是我的URL路径< code > this . router . navigate([' BD-activity/dynamic form ',{ id: event.customer_id,opportunity_id: event。_ id }]);我希望它在另一个选项卡中打开。 我试过这个(URL,_blank)。这在这里不起作用。我正在研究角度11。如果你们有任何建议,请告诉我。我是An
问题内容: 我的表设置如下: 我想构造一个select语句,该语句将显示在value_search中没有条目的所有进程名称(带有其各自的id_string)。 进程表中的id_string可以为 null ,并且仍然具有名称,但是如果可能的话,必须将其排除。value_search中的id_string永远不能为 null 我该怎么做呢? 问题答案: 通常,如果您想要其他表中不存在的行,则将LEF
问题内容: 我想检查某个网站是否存在,这就是我正在做的事情: 如果该页面不存在(错误402或其他任何错误),我可以在该行中做什么以确保正在读取的页面退出? 问题答案: 您可以使用HEAD请求而不是GET。它将仅下载标题,而不下载内容。然后,您可以从标题中检查响应状态。 或者你可以使用 或者你可以使用
我有一个手风琴,这是工作绝对好,但我需要的是,只打开一个标签一次,这意味着当一个标签打开,然后另一个标签应该关闭。 目前,您可以看到,我们可以通过单击选项卡链接打开所有选项卡。 代码在这里 这里是小提琴
我的两个列表中有以下元素,清单1[A F K]和清单2[B A C F K]。清单1的所有元素都在清单2中,因此它应该返回true 我尝试使用list1.containsAll(list2),但它并不支持我。 我尝试在这两个列表中循环,如果找到匹配,我就清空第一个列表中的那个位置,但这不起作用,因为我认为它会受到并发修改的影响。这是我的代码 在这里,subTreeList最终输出[A]。我知道它会