【问题标题】:Prevent Refresh of SSI防止刷新 SSI
【发布时间】:2012-10-08 22:43:29
【问题描述】:

我有一些 SSI 在我的网站内的许多页面中重复出现 - 特别是我的导航树,它允许用户展开或折叠树中的节点。

如果相同的 .shtml 文件已在前一页中加载,我想阻止它加载 - 这样,当用户单击我的导航树中的一个条目时,整个树不会刷新到目标页面(这会导致用户的当前节点被折叠)。关于如何实现这一点的任何想法?

【问题讨论】:

    标签: server-side-includes


    【解决方案1】:

    一种方法是将导航树放在单独的框架中(不是 iframe),这会带来其自身的问题;由于包含发生在服务器端,因此包含的内容中导致页面刷新的任何内容都将刷新整个页面,而不考虑通过 SSI 包含的内容和未包含的内容。将树放在自己的框架中,并将其链接修改为指向内容框架,您就不会有这个问题——当然,使用框架来解决这个问题只会给您带来另一个问题。

    更好的选择是使用 cookie 和 Javascript 来记录树的哪些节点被展开。您可以将单击处理程序绑定到每个节点扩展器/收缩器,该处理程序将更新表示树状态的 Javascript 对象,并且在每个单击事件中,将该对象展平为字符串并通过 document.cookie 存储。这样,您可以将树状态保持到下一个页面加载中,此时 onload 处理程序可以展开 cookie 中列出的节点,以将树返回到单击页面重新加载链接时的状态。

    这样的事情可能会起作用,假设存在 jQuery,无论是具有原生 JSON 支持的浏览器还是加载的等效库,您的节点扩展器/收缩器控件被实现为具有类“node-control”的 标签,扩展节点的控件具有“扩展”类(可能由预先存在的单击处理程序提供),并且每个节点都有一个 id 属性,该属性唯一地标识其在树中的位置。

     // begin "persistent-node-state.js"
    
     window.nodesExpanded = {};
    
     // do the following on document load completion: 
     jQuery(document).ready(function() {
       // check for a nodesExpanded value in the cookie
       var cookieMatch = document.cookie.match(/nodesExpanded=(.*?)\;/);
       if (cookieMatch) { // no nodesExpanded cookie found -- do nothing
         // we found a nodesExpanded cookie; let's unserialize its value into
         // window.nodesExpanded
         window.nodesExpanded = JSON.parse(cookieMatch[1]);
       };
    
       // iterate through the nodesExpanded object's keys, which are IDs of controls whose
       // nodes we want to expand (if we didn't find a cookie, then window.nodesExpanded 
       // is an empty object, making this loop a very complicated no-op)
       for (node_id in nodesExpanded) {
         // call the pre-existing click handler to expand the node
         jQuery('a.node_control#' + node_id).click();
       };
    
       // now that that's done, give each node control an additional click handler which 
       // puts its state into window.nodesExpanded and updates the cookie
       jQuery('a.node-control').click(function(i,el) {
         var node_id = jQuery(el).attr('id');
    
         // if this control's node is expanded...
         if (jQuery(el).hasClass('expanded')) {
           // ...then add the control's id as a key in window.nodesExpanded...
           window.nodesExpanded[node_id] = true;
         }
         else {
           // ...otherwise remove any existing key in window.nodesExpanded with this 
           // node's ID
           window.nodesExpanded[node_id] = undefined;
         };
    
         // store the updated state in the cookie so it'll persist across page loads
         document.cookie('nodesExpanded=' + JSON.stringify(window.nodesExpanded));
       });
     });
    
     // end "persistent-node-state.js"
    

    当然,所有这些都可以在没有 jQuery 的情况下完成,但加载该库并不需要太多成本——你甚至不必下载它,但 load it from Google's CDN 可以——它使一切使用 Javascript 更容易,除非您需要支持非常旧的(例如 IE6 之前的)浏览器或类似的东西,否则没有很好的理由不这样做。

    同样,所有各种提示(即,如何识别节点扩展/收缩控件、如何判断它是否已扩展、如何触发导致节点扩展或收缩的事件等)都可以修改有需要;在没有站点链接或一些示例代码的情况下,很难根据您的情况定制一个示例,所以我选择了尽可能通用的东西,同时仍然展示了基本思想,并且不应该太难编辑以品尝.

    【讨论】:

    • 我认为必须发生这样的事情。我想我也可以使用 sessionStorage 将用户的当前节点存储在导航树中。
    • 当然可以,但是当你真的不需要的时候,为什么要引入 HTML5 依赖呢?我的意思是,您正在使用 SSI,您已经牢牢扎根于过去......
    【解决方案2】:

    服务器端包含就是这样,服务器端。如果您在多个页面中有相同的包含文件,则每次都会包含它。 Apache(或 IIS)将看到这一点。另一方面,如果在构建单个“页面”时,同一个文件包含在多个包含文件中,您可以在包含的文件中设置一个变量,并在文件被包含的每个位置进行测试。我使用为我的站点设置全局变量的配置文件来做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-25
      • 2020-01-25
      • 1970-01-01
      • 2010-10-18
      • 2014-02-14
      • 2020-03-17
      • 1970-01-01
      相关资源
      最近更新 更多