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

时间:2010-10-27 23:47:50

标签: javascript browser tabs user-experience

我只想到整个网站注册流程。

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

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

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

我在想,如果我们可以检测到用户是否已经打开了您网站的标签,那么我们可以自动关闭新的验证标签,或者告诉他可以关闭它可以回到他的另一个标签(我们现在已经刷新并登录了他)。

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

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


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

8 个答案:

答案 0 :(得分:40)

我在这里参加聚会已经相当晚了(一年多了),但我不禁注意到你错过了一个非常简单和优雅的解决方案(可能也就是你看过的那个网站)。

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

window.name = "myWindow";

然后当您发送确认电子邮件时(假设您正在发送HTML电子邮件):

<a href="verificationlink.php" target="myWindow">Verify</a>

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

答案 1 :(得分:6)

您可以从原始标签每隔 X 秒发送一个AJAX请求,询问服务器是否收到了电子邮件中的请求。

您无法自动关闭第二个标签,但是您可以在 3X 秒后询问服务器是否从第一个标签中听到。

答案 2 :(得分:6)

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

$(window).blur(function(){
    // code to stop functioning or close the page  
});

答案 3 :(得分: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);
}

答案 4 :(得分:2)

用户仍将在服务器上进行会话。为什么不在注册之前存储用户的位置,当他们确认注册时,请从会话中读回位置并重定向回该页面。不需要制表魔法。这肯定不是我对注册过程的期望。

答案 5 :(得分:2)

要充实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>

答案 6 :(得分:1)

要添加其他答案: 您也可以使用localStorage。有像“openTabs&#39;”这样的条目。打开页面时,请增加此数字。当用户离开页面时,请将其减少。

答案 7 :(得分:1)

通过将数据保存在每个标签的localstorage中并进行计数,可以跟踪您打开的网站的标签数,我创建了一个github repository,它可以跟踪您网站的标签数用户已打开。

要使用它,请在页面中包含 tab-counter.js ,它将开始跟踪已打开的标签页的数量。

console.log(tabCount.tabsCount());