我们有一个包含多个
块的HTML页面。我们想将这些div分离成多个文件,然后将它们合并成一个单独的文件 - 最好使用服务器端包含(在我们的情况下是JSP)还是客户端包含?请注意,我们正在使用JQuery - 不确定JQuery是否有巧妙的方法来执行包含操作。
实际上,客户端包含有一个非常有用的属性:客户端浏览器具有缓存!如果您的某些内容不经常更改,并且每个客户端经常加载页面的某个片段,则客户端包含是一个好主意,因为可以利用客户端浏览器缓存。
想法是您的完整页面包含一堆占位符div,其中将放置客户端包含。通过AJAX调用加载HTML片段。如果片段的HTTP响应标头指定了很久以后的Expires和/或Cache-Control,当您的客户端访问下一个页面时,AJAX请求将从缓存中服务,而不是实际地到服务器。
我不确定自己在客户端与服务器端辩论中属于哪一方。现在流行的做法似乎是在客户端处理事情。也许两者的结合最好。为了完全在客户端尝试它,我决定启动一个对象,异步执行客户端包含操作,但缓存文本以供以后使用。有一个加载函数,它将回调函数作为参数调用成功加载时。还有一个将对象的内部HTML设置为加载的文本的函数。该对象需要先前包含jquery。
/**
* An object to manage client side includes.
*
* Loads of text are asynchronous but the result will be cached for later use.
*
* @param urlText - the url of the inlcude text
* @returns an Include object
*/
function Include(urlText)
{
var self;
var loaded;
var txt;
var url;
/**
* Sets the url for the include.
*
* Will unload a previously set include.
*
* @param url
*/
this.setUrl = setUrl;
function setUrl(url)
{
if (self.url != url)
{
unload();
}
self.url = url;
}
/**
*
* @returns the url
*/
this.getUrl = getUrl;
function getUrl()
{
return self.url;
}
/**
* Unloads the current url.
*/
this.unload = unload;
function unload()
{
self.txt = null;
self.loaded = false;
}
/**
* Loads the current url asynchronously
*
* @param fnPostLoad function to call on successful completion
*/
this.load = load;
function load(fnPostLoad)
{
if (self.loaded)
{
if (fnPostLoad != null)
{
fnPostLoad.call();
}
return;
}
$.ajax({
type : "GET",
dataType : "text",
url : self.url,
success : function(data) {
self.txt = data;
self.loaded = true;
if (fnPostLoad != null)
{
fnPostLoad.call();
}
},
error : function(){
alert("An error occurred accessing client side include located at: " + self.url);
}
});
};
/**
* Sets the inner html of a given object to be the text of this include.
*
* Will load the url if not loaded.
*
* @param obj
*/
this.setInnerHtmlOf = setInnerHtmlOf;
function setInnerHtmlOf(obj)
{
load(function(){obj.html(self.txt);})
}
// initialize members
self = this; // must be done first
loaded = false;
txt = null;
setUrl(urlText);
}
要使用这个对象,您可以这样做:
var foo = new Include("foo.inc");
var bar = new Include("bar.inc");
foo.setInnerHtmlOf($('#treeMargin'));
bar.setInnerHtmlOf($('#mainMargin'));
我还没有做太多的测试,但它似乎运行得相当不错。
我必须同意其他人的看法,服务器端是最好的选择,但有一个例外。
如果你的部分包含需要较长时间加载的内容,比如每个部分都需要从不同的Web服务调用中获取内容,那么使用JQuery通过get方法异步加载它们可能会更有益,因为在加载部分时可以同时加载页面的其余部分。
除此之外,确实...应该在服务器端处理。
我会说是服务器端。如果jQuery没有加载或用户关闭了JavaScript,怎么办?