How to cache a jquery Ajax request and parsing
I'm building an application that is an image gallery but with lots of images (it's for browsing archives of documents); basically the application does this:
- display an image
- display "previous" and "next" links left and right of the first image
The previous and next links are retrieved from an XML file that lists all images in sequence; there are around 1000-2000 images in each set (one XML file per set). In order to avoid having to look for preceding and following sibling elements, I included the names of each previous and next images as attributes of each image.
So the XML file is basically:
<list>
...
<image previous="ww.jpg" next="yy.jpg">xx.jpg</image>
<image previous="xx.jpg" next="zz.jpg">yy.jpg</image>
<image previous="yy.jpg" next="aa.jpg">zz.jpg</image>
...
</list>
What I'm doing is this:
function display(img) {
var lookingfor = 'image:contains('+img+')';
$.ajax({
type: "GET",
url: "pns.xml",
dataType: "xml",
success: function(xml) {
$(xml).find(lookingfor).each(function(){
// display the actual image and the links from @previous and @next attributes
});
}
});
}
$(document).ready(function(){
var image = $.query.get('img');
display(image);
});
The first time the page loads, the script:
- gets the name of the image to be displayed from the url parameter 'img'
- loads the xml file containing the name of all images
- gets previous and next image names from this same file
- displays the image
- displays links to the previous and next images
So far so good. My problem is with the other images.
The link to the previous or next image is:
display('image_id');
I was hoping that without reloading the page and simply calling again the 'display' function I would not have to get the XML file again, and no开发者_开发技巧t have to parse it again. However, it seems to not be the case: the XML file is apparently loaded again with every new call of the 'display' function.
A significant delay the first time the page is loaded is acceptable; but the same delay for each image seems sluggish and very unpleasant.
I have full control over the application; if there is a more efficient solution than an XML file to hold the parameters that would be fine. However the application has to work offline, so I cannot query a server to get the names of preceding / following images.
Also, using the :contains() selector is probably not the fastest approach: what would be better?
Edit: using XML and loading it externally was clearly far from optimal; a much better and simpler approach is to have a big object containing one array per image and to load this object just once (when the script is first loaded). Another approach would be to use some local storage / SQL facility; I may try this with Google Gears which provide such tools.
Perhaps Ajax the image XML into a global JS variable the first time and then just query the JS variable on subsequent calls. So:
<script type="text/javascript">
var imgXML = null;
// document ready
$(function() {
$.ajax({
type: "GET",
url: "pns.xml",
dataType: "xml",
success: function(xml) {
imgXML = xml;
var image = $.query.get('img');
display(image);
}
});
}
// subsequent display goes straight to the XML data in memory
function display(img) {
if(imgXML != null) {
var lookingfor = 'image:contains('+img+')';
$(imgXML).find(lookingfor).each(function(){
// display image and links
}
}
}
</script>
I'm sure there's other optimizations to be made but this should solve your re-loading the XML problem.
How about setting cache
to true
?
$.ajaxSetup({
cache: true
});
One way is to fetch xml file before getting first image separately (from image fetching function) and read all image names in an array (though it will be a big array).
//pseduo code
<script type="text/javascript">
var currentImage=-1;
var imageName=new Array();
loadXML(){
GETXML;
var i=0;
for(image in images_in_xml){
imageName.push(image);
if(image == CURRENT_IMAGE_NAME)
currentImage = i;
i++;
}
}
</script>
Now you have index of current image and you can easily get name of next and previous image by simply using currentImage-1
and currentImage+1
Looks like you're making a request for the full xml each time, which is in many cases not the best idea. Depending on your situation you might want to use an optimized database, a smaller/optimised dynamic xml solution or start looking for an expert...
From the brief description you give, I would suggest a jquery lightbox plugin - but of course you might have a reason not to use that option.
By the way, I noticed you wrote "A significant delay the first time the page is loaded is acceptable" and am trying to understand the logic... The first time a visitor comes to your site is the first impression, and everybody knows that first impressions last (especially online, where 3 seconds feels like an eternity)'
精彩评论