【问题标题】:Restriction on number of opened tabs打开标签的数量限制
【发布时间】:2015-08-23 22:50:06
【问题描述】:

网页上有一些链接。

右键单击有“在新选项卡中打开链接”选项(浏览器选项)。

我想限制用户不要打开两个以上的标签? 我该怎么做?

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<ul>
<li><a href="http://localhost:8080/struts_tab/abcForm1.action" oncontextmenu="return false;"><span>First Click[Right Click disabled]</span></a></li>
<li><a href="http://localhost:8080/struts_tab/defForm2.action"><span>Second clieck[Not more than 2 tabs]</span></a></li>
</ul>
</body>
</html>

【问题讨论】:

    标签: javascript jsp web struts2 browser-tab


    【解决方案1】:

    您不能限制用户打开新标签。
    (这让我想起了没有按钮、没有地址栏但仍然响应的旧弹出窗口退格和其他事件)

    但是,您可以让您的应用识别打开第三个标签页的尝试,并加载不同的结果,例如错误消息,例如:

    已达到最大打开标签限制。请同时使用不超过两个选项卡。 关闭此标签

    为此,您可以使用HTML5 sessionStorage
    注意:Web 存储sessionStoragelocalStorageis supported on every browser 现在。

    会话存储

    这是一个全局对象 (sessionStorage),维护一个存储区域 在页面会话期间可用。页面会话 只要浏览器打开并在页面上存活,就会持续 重新加载和恢复。 在新标签页或窗口中打开页面会导致 将启动一个新会话

    那你就可以了

    • 如果 sessionStorage 中不存在,则在 JSP 中生成一个唯一令牌,并将其放入 sessionStorage 中,

      $(function(){
          // Read the ID. If it's null, this is a new tab: 
          // generate the ID and store it for later.
          var tabId = sessionStorage.getItem("tabId");
          if (tabId == null){
              tabId = Math.random();
              sessionStorage.putItem("tabId",tabId);
          }
      
    • 将其发送回操作

          // Add the ID to the form (as hidden field), 
          // so it will be posted back in next submission.
          $('<input>').attr('type'  , 'hidden')
                      .attr('name'  , 'tabId')
                      .attr('value' , tabId)
          .appendTo('form');
      });
      

      ,可能是 BaseAction 中的 setter,由其他操作扩展,并由 prepare() 读取,或者在拦截器中更好

    • 把它放在一个集合中,检查它是否已经包含两个元素,否则返回错误结果,应该全局映射:

      public String intercept(ActionInvocation actionInvocation) throws Exception {
          Action action = (Action) actionInvocation.getAction();
          if(action instanceof LimitedTabsAware){ //interface to identify special actions
              ActionContext context = actionInvocation.getInvocationContext();
              Map<String, String[]> request = ((HttpServletRequest) 
                                  context.get(StrutsStatics.HTTP_REQUEST)).getParameterMap();
      
              if (request.containsKey("tabId")){              
                  String tabId = (String) request.get("tabId")[0];
                  List<String> openTabs = context.getSession().get("OPEN_TABS_KEY");
      
                  if (openTabs.contains(tabId)){
                      return actionInvocation.invoke();                   
                  } else if (openTabs.size()>=2){
                      return "tabLimitExceeded"; // global result
                  } else {
                      openTabs.add(tabId);
                      context.getSession().put("OPEN_TABS_KEY", openTabs);
                      return actionInvocation.invoke();
                  }
      
              } else {
                  throw new IllegalArgumentException("There is no tabId in this request.");
              }
          } else {
              return actionInvocation.invoke();
          }
      }
      

    然后您应该找到一种方法来识别选项卡何时关闭(以释放一个插槽),方法是:

    • timizing the period of validity of the elements 在您的集合中(如果您有一段时间不使用选项卡,会话将过期,因此必须在集合中使用令牌)
    • 否则,在您的页面中放置一个javascript AJAX timer(例如,每30 秒一次),这会向操作发送一个keep-alive 信号以刷新元素的有效性。如果选项卡关闭,则不再发送信号。

    【讨论】:

      猜你喜欢
      • 2014-02-18
      • 1970-01-01
      • 2021-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-30
      • 1970-01-01
      • 2022-11-18
      相关资源
      最近更新 更多