代码之家  ›  专栏  ›  技术社区  ›  mpen

是否可以检测用户是否打开了站点的多个选项卡?

  •  31
  • mpen  · 技术社区  · 14 年前

    我只是在考虑整个网站注册过程。

    用户进入你的网站,注册,然后你告诉他你给他发了一封电子邮件,他需要验证他的电子邮件地址。所以他打了 Ctrl键 T型 ,弹出一个新标签,点击他的 Gmail fav按钮,不读你冗长的欢迎邮件,但点击他看到的第一个链接。Gmail在另一个标签页中打开你的站点。。。

    他不需要也不想为你的网站打开两个标签,他只想查看你已经禁止他访问的该死的页面,直到他注册。

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

    我在想,如果我们能够检测到用户是否已经打开了站点的一个选项卡,我们可以自动关闭新的验证选项卡,或者告诉他可以关闭它,可以返回到他的另一个选项卡(我们现在已经刷新并登录了他)。

    或者,当他收到你烦人的“请检查你的电子邮件”信息时,他直接转到他的电子邮件,用他的电子邮件替换你的网站,他很清楚电子邮件会再次将他链接到网站。在这种情况下,我们不想关闭标签,但也许可以从以前保存他的位置,并再次将他重定向到那里?

    无论如何,这只是用例。。。这个问题仍然存在。 我们是否可以检测用户是否已经打开了站点的选项卡?


    这个问题是 关于如何检测 什么时候

    8 回复  |  直到 14 年前
        1
  •  43
  •   Elmo Shikha Dhawan    12 年前

    我来这里的派对已经晚了(一年多了),但我不得不注意到你错过了一个非常简单和优雅的解决方案(可能还有你看到的那个网站使用的)。

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

    window.name = "myWindow";
    

    然后,当您发送确认电子邮件时,只需执行以下操作(假设您发送的是HTML电子邮件):

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

    verificationLink 打开您的网站已加载到的窗口内,如果该窗口已关闭,则将打开指定窗口名称的新选项卡。

        2
  •  6
  •   SLaks    14 年前

    您可以在每个 从询问服务器是否收到来自电子邮件的请求的原始选项卡开始的秒数。

    您不能自动关闭第二个选项卡,但可以让它在之后询问服务器 3倍

        3
  •  6
  •   mpen    11 年前

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

    $(window).blur(function(){
        // code to stop functioning or close the page  
    });
    
        4
  •  6
  •   Anthony Vipond    7 年前

    // 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);
    }
    
        5
  •  3
  •   Neil VanLandingham    6 年前

    为了充实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
  •  2
  •   spender    14 年前

    用户仍将在服务器上有一个会话。为什么不在注册之前存储用户的位置,当他们确认注册时,从会话中读取位置并重定向回该页面。不需要标签魔术。这当然不是我对注册过程的期望。

        7
  •  2
  •   Jānis    7 年前

    也可以使用本地存储。有一个类似“openedTabs”的条目。打开网页后,请增加此数字。当用户离开页面时,将其缩小。

        8
  •  1
  •   Shub    6 年前

    通过将数据保存到 localstorage 在每一个标签的计数相同的情况下,我创建了一个 github repository

    使用它包括 在您的页面中,它将开始跟踪打开的选项卡数。

    console.log(tabCount.tabsCount());