可以检测用户是否打开了您网站的多个标签?

mpe*_*pen 32 javascript browser tabs user-experience

我只想到整个网站注册过程.

用户访问您的网站,注册,然后您告诉他您已向他发送了一封电子邮件,他需要验证他的电子邮件地址.所以他点击Ctrl+ T,弹出一个新的标签,点击他的Gmail收藏按钮,没有阅读你冗长的欢迎电子邮件,但点击他看到的第一个链接.Gmail会在另一个标签中打开您的网站...

他不需要也不想要两个标签打开你的网站,他只是想查看你禁止他访问的那个页面,直到他注册.

那么我们该怎么办?我看到一个网站(但我忘记它是什么)做得非常好,它实际上刷新了我打开的第一个标签,而不必按任何东西.

我想,如果我们可以检测到用户是否已经打开了您网站的标签,我们可以自动关闭新的验证标签,或者告诉他可以关闭它可以返回到其他选项卡,这可能会很好(我们现在已经刷新并登录了他).

或者,也许当他得到你讨厌的"请检查你的电子邮件"消息时,他直接转到他的电子邮件,用他的电子邮件替换你的网站,知道电子邮件会再次将他链接回网站.在这种情况下,我们不想关闭标签,但也许可以从之前保存他的位置,并再次将他重定向到那里?

无论如何,这只是用例...问题仍然存在.我们是否可以检测用户是否已打开您网站的标签?


此问题与如何检测用户何时完成注册过程无关.Ajax民意调查或彗星可以解决这个问题.我特别想知道用户是否已经在您的网站上打开了一个标签.

小智 42

我在这里参加派对已经相当晚了(一年多了),但我不禁注意到你错过了一个非常简单和优雅的解决方案(也许你看过的网站是什么用的).

使用JavaScript,您可以更改当前打开的窗口的名称:

window.name = "myWindow";
Run Code Online (Sandbox Code Playgroud)

然后,当您发送确认电子邮件时,只需(确认您正在发送HTML电子邮件):

<a href="verificationlink.php" target="myWindow">Verify</a>
Run Code Online (Sandbox Code Playgroud)

这应该会导致verificationLink您的网站已经加载到窗口内部,如果它已经关闭,它将打开一个指定窗口名称的新选项卡.

  • 这并没有真正回答这个问题:"我们可以检测用户是否已经打开了您网站的标签页吗?" 另一个例子是,如果用户在您的网站上打开了两个窗口,则需要警告用户. (4认同)
  • 如果在两个不同的浏览器中打开页面,则无效.但当然在问题中没有提到,所以我说的是什么?:d (3认同)

SLa*_*aks 6

您可以每隔X秒从原始选项卡发送一个AJAX请求,询问服务器是否收到了来自电子邮件的请求.

您无法自动关闭第二个选项卡,但可以让它在3X秒后询问服务器是否从第一个选项卡中听到.


小智 6

当用户打开另一个选项卡或其他窗口或甚至另一个浏览器时,您可以停止页面功能

$(window).blur(function(){
    // code to stop functioning or close the page  
});
Run Code Online (Sandbox Code Playgroud)


Ant*_*ond 5

我在这里遇到的用例与您有些不同,但是它可以检测是否在另一个选项卡中访问了该站点。在这种情况下,我想将使用某些呼叫中心页面的人员限制为一个选项卡。它运作良好,并且完全是客户端。

// helper function to set cookies
function setCookie(cname, cvalue, seconds) {
    var d = new Date();
    d.setTime(d.getTime() + (seconds * 1000));
    var expires = "expires="+ d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

// helper function to get a cookie
function getCookie(cname) {
    var name = cname + "=";
    var decodedCookie = decodeURIComponent(document.cookie);
    var ca = decodedCookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

// Do not allow multiple call center tabs
if (~window.location.hash.indexOf('#admin/callcenter')) {
    $(window).on('beforeunload onbeforeunload', function(){
        document.cookie = 'ic_window_id=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;';
    });

    function validateCallCenterTab() {
        var win_id_cookie_duration = 10; // in seconds

        if (!window.name) {
            window.name = Math.random().toString();
        }

        if (!getCookie('ic_window_id') || window.name === getCookie('ic_window_id')) {
            // This means they are using just one tab. Set/clobber the cookie to prolong the tab's validity.
            setCookie('ic_window_id', window.name, win_id_cookie_duration);
        } else if (getCookie('ic_window_id') !== window.name) {
            // this means another browser tab is open, alert them to close the tabs until there is only one remaining
            var message = 'You cannot have this website open in multiple tabs. ' +
                'Please close them until there is only one remaining. Thanks!';
            $('html').html(message);
            clearInterval(callCenterInterval);
            throw 'Multiple call center tabs error. Program terminating.';
        }
    }

    callCenterInterval = setInterval(validateCallCenterTab, 3000);
}
Run Code Online (Sandbox Code Playgroud)


Nei*_*ham 5

为了充实 John 的答案,这里有一个可行的解决方案,它使用纯 JS 和 localStorage 并使用当前打开的选项卡的数量更新 DOM。请注意,此解决方案检测一个浏览器中给定域打开的选项卡/窗口的数量,但不会维护不同浏览器之间的计数。

它使用存储事件来保持所有打开的选项卡/窗口之间的计数同步,而无需刷新页面。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="robots" content="noindex, nofollow">
<meta name="googlebot" content="noindex, nofollow">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script>
(function() {
    var stor = window.localStorage;
    window.addEventListener("load", function(e) {
        var openTabs = stor.getItem("openTabs");
        if (openTabs) {
            openTabs++;
            stor.setItem("openTabs", openTabs)
        } else {
            stor.setItem("openTabs", 1)
        }
        render();
    })
    window.addEventListener("unload", function(e) {
        e.preventDefault();
        var openTabs = stor.getItem("openTabs");
        if (openTabs) {
            openTabs--;
            stor.setItem("openTabs", openTabs)
        }
        e.returnValue = '';
    });
    window.addEventListener('storage', function(e) {
        render();
    })

    function render() {
        var openTabs = stor.getItem("openTabs");
        var tabnum = document.getElementById("tabnum");
        var dname = document.getElementById("dname");
        tabnum.textContent = openTabs;
        dname.textContent = window.location.host
    }
}());
</script>
</head>
<body>
<div style="width:100%;height:100%;text-align:center;">
    <h1 >You Have<h1>
        <h1 id="tabnum">0</h1>
    <h1>Tab(s) of <span id="dname"></span> Open</h1>
</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)