我有一些 SSI 在我的站点内的许多页面中重复 - 特别是我的导航树,它允许用户展开或折叠树中的节点。
我想阻止加载相同的 .shtml 文件,如果它已经在前一页中加载 - 这样当用户点击我的导航树中的一个条目时,整个树不会刷新到目标页面(这会导致用户的当前节点被折叠)。关于如何实现这一点的任何想法?
我有一些 SSI 在我的站点内的许多页面中重复 - 特别是我的导航树,它允许用户展开或折叠树中的节点。
我想阻止加载相同的 .shtml 文件,如果它已经在前一页中加载 - 这样当用户点击我的导航树中的一个条目时,整个树不会刷新到目标页面(这会导致用户的当前节点被折叠)。关于如何实现这一点的任何想法?
一种方法是将导航树放在单独的框架中(而不是 iframe),这会带来其自身的问题;由于包含发生在服务器端,因此包含的内容中导致页面刷新的任何内容都将刷新整个页面,而不考虑通过 SSI 包含的内容和未包含的内容。将树放在自己的框架中,并将其链接修改为指向内容框架,您就不会有这个问题——当然,使用框架来解决这个问题只会给您带来另一个问题。
更好的选择是使用 cookie 和 Javascript 来记录树的哪些节点被扩展。您可以将单击处理程序绑定到每个节点扩展器/收缩器,该处理程序将更新表示树状态的 Javascript 对象,并且在每个单击事件中,将该对象展平为字符串并通过 document.cookie 存储。这样,您可以将树状态保存到下一个页面加载中,其中 onload 处理程序可以展开 cookie 中列出的节点以将树返回到单击页面重新加载链接时的状态。
假设存在 jQuery(具有原生 JSON 支持的浏览器或加载的等效库),您的节点扩展器/收缩器控件被实现为具有类“node-control”的 <a> 标记,那么这样的事情可能会起作用,即控件对于扩展节点具有“扩展”类(可能由预先存在的单击处理程序给出),并且每个节点都有一个 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 的情况下完成,但加载该库并不需要太多成本——你甚至不必下载它,而是可以从 Google 的 CDN 加载它——它让一切都可以做使用 Javascript 会容易得多,除非您需要支持非常旧的(例如 IE6 之前的)浏览器或具有一般性质的东西,否则没有很好的理由不这样做。
类似地,所有各种提示(即,如何识别节点扩展/收缩控件、如何判断它是否已扩展、如何触发导致节点扩展或收缩的事件等)都可以根据需要进行修改;在没有站点链接或一些示例代码的情况下,很难根据您的情况定制一个示例,所以我选择了尽可能通用的东西,同时仍然展示了基本想法,并且不应该太难编辑以品尝.
服务器端包括服务器端。如果您在多个页面中有相同的包含文件,则每次都会包含它。Apache(或 IIS)将看到这一点。另一方面,如果在构建单个“页面”时,同一个文件包含在多个包含文件中,您可以在包含的文件中设置一个变量,并在文件包含的每个位置对其进行测试。我使用为我的站点设置全局变量的配置文件来做到这一点。