<?xml version="1.0" encoding="UTF-8"?>
<imageset xmlns:tns="http://www.example.org/images" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/images images.xsd ">
<image>
<filename>Capture_08092007_171921.jpg</filename>
<date>2008-12-23</date>
</image>
<image>
<filename>Capture_08092007_171901.jpg</filename>
<date>2008-12-26</date>
</image>
<image>
<filename>Capture_08092007_171551.jpg</filename>
<date>2008-12-25</date>
</image>
</imageset>
Here is the XML schema file:
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/images" xmlns:tns="http://www.example.org/images" elementFormDefault="qualified"> <element name="imageset"> <complexType> <all> <element name="image"> <complexType> <all> <element name="filename" type="string" /> <element name="date" type="date" /> </all> </complexType> </element> </all> </complexType> </element> </schema>
Now the code is first called with this parameter from an onclick event: viewEnlarged("pics/images/Capture_08092007_171921.jpg"). The code associated with the problem is this:
/**
* Loads an xml file into a parser object and return the object.
* @param String filename The filename
* @return Object The xml parser.
*/
function xmlLoadFileParser(filename)
{
var xmlDoc;
if(IE)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.load(filename);
}
else
{
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = "false";
xmlDoc.load(filename);
}
return xmlDoc;
}
function viewEnlarged(picture)
{
if(boolDoAgain == "Open")
{
if(FF || NS)
{
unitPostfix = "px";
}
animation_time = 0;
width = 0;
height = 0;
darkLayer = CreateDynamicLayer("darkLayer");
pictureLayer = CreateDynamicLayer("pictureLayer");
// Layer style
if(IE)
{
darkLayer.style.filter = "alpha( style=0,opacity=" + DARK_LAYER_OPACITY * 100 +")";
}
else
{
darkLayer.style.opacity = DARK_LAYER_OPACITY;
}
centerLayer();
loadFilenames();
// find the current picture in the gallery
pictureIndex = indexOfFilename(picture.substring(picture.lastIndexOf("/") + 1));
// display loading as needed
pictureLayer.innerHTML = "<img src=\"" + LOADING_PIC + "\" />";
picObj = new Image();
picObj.onload = openEnlargedPicture;
picObj.src = picture;
}
}
function indexOfFilename(filename)
{
var found = false;
var index = -1;
for(var i = 0; i < pictures.length && !found; i++)
{
if(pictures[i][1] == filename)
{
found = true;
index = i;
}
}
return index;
}
/**
* Loads the file names of the images so we can go forward and backward.
* @access private
* @return
*/
function loadFilenames()
{
var xmlDoc = xmlLoadFileParser("pics/images.xml");
// raw data
var filenameNodes = xmlDoc.getElementsByTagName("filename");
var dateNodes = xmlDoc.getElementsByTagName("date");
// create a table with the following fields -- date, filename -- using a two dimensional array.
for(var i = 0; i < filenameNodes.length && i < dateNodes.length; i++)
{
pictures.push(new Array(dateNodes[i].firstChild.nodeValue, filenameNodes[i].firstChild.nodeValue));
}
pictures.sort(sortByDate)
}
/**
* Sorts two records passed as 1-D arrays. The date MUST be the first value in the array.
* @param Array record1 The first record.
* @param Array record2 The second record.
*/
function sortByDate(record1, record2)
{
return compareDates(record1[0], record2[0]);
}
/**
* Compares 2 dates returning a negative number if the first date is smaller than the second one,
* a positive number if the first date is greater than the second date, and zero if the dates are equal.
* @param String strDate1 The first date. Format: "yyyy-mm-dd".
* @param String strDate2 The second date. Format: "yyyy-mm-dd".
* @access private.
* @return
*/
function compareDates(strDate1, strDate2)
{
var splitDate1 = strDate1.split("-");
var splitDate2 = strDate2.split("-");
var date1 = new Date(splitDate1[0], splitDate1[1] - 1, splitDate1[2] - 1);
var date2 = new Date(splitDate2[0], splitDate2[1] - 1, splitDate2[2] - 1);
return date1.valueOf() - date2.valueOf();
}
function showNextPicture()
{
destroyEnlargedPicture();
viewEnlarged(imagesDir + "/" + pictures[pictureIndex + 1][1]);
}
The problem occurs on in the showNextPicture() function in Firefox. For some reason pictures is empty. But when I go through it using a step by step debugger it works fine. The function responsible for filling that array with data is loadFileNames(). Now, a problem like that usually means that the file was not loaded before the code was executed. But, as you can see, I set async to false in xmlLoadFileParser() which actually loads the XML file and returns a parser object. So I am quite lost honestly. In IE this works just fine.
All the code:
/**
* Loads an xml file into a parser object and return the object.
* @param String filename The filename
* @return Object The xml parser.
*/
function xmlLoadFileParser(filename)
{
var xmlDoc;
if(IE)
{
xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
xmlDoc.async = "false";
xmlDoc.load(filename);
}
else
{
xmlDoc = document.implementation.createDocument("", "", null);
xmlDoc.async = "false";
xmlDoc.load(filename);
}
return xmlDoc;
}
/**
* This module is used to open a picture using a nice animation effect.
* @author Michael Yagudaev
* @copyrights Michael Yagudaev
* @version 2.0
*/
// constants
var PICTURE_PADDING = 40;
var DARK_LAYER_OPACITY = 0.7;
var ANIMATION_LENGTH = 2500; // length in miliseconds
var INTERVAL = 50;
var NUMBER_FRAMES = ANIMATION_LENGTH / INTERVAL;
var LOADING_PIC = "/images/Loading.gif";
var PREV_ICON = "/images/left_arrow_icon.gif";
var PREV_DISABLED_ICON = "/images/left_arrow_disabled_icon.gif";
var NEXT_ICON = "/images/right_arrow_icon.gif";
var NEXT_DISABLED_ICON = "/images/right_arrow_disabled_icon.gif";
var CLOSE_ICON = "/images/close_icon.gif";
var imagesDir = "pics/images";
var animation_time;
var width;
var height;
var boolDoAgain = "Open";
var unitPostfix = "";
var maxWidth;
var maxHeight;
var speed;
var pictureLayer;
var darkLayer;
var speedFactor;
var statusLayer;
var picObj;
var picRatio;
var loadingLayer;
var pictures = new Array(); // A table with the following fields: date, filename.
var pictureIndex = -1; // The picture number in the current gallery
//preload loading graphics
var loadingObj = new Image();
var closeIconObj = new Image();
var prevIconObj = new Image();
var nextIconObj = new Image();
var prevIconDisabled = new Image();
var nextIconDisabled = new Image();
loadingObj.src = LOADING_PIC;
closeIconObj.src = CLOSE_ICON;
prevIconObj.src = PREV_ICON;
nextIconObj.src = NEXT_ICON;
loadExternalFile("css/animation_effects.css", "css");
/**
*
* @param picture
* @return
*/
function viewEnlarged(picture)
{
if(boolDoAgain == "Open")
{
if(FF || NS)
{
unitPostfix = "px";
}
animation_time = 0;
width = 0;
height = 0;
darkLayer = CreateDynamicLayer("darkLayer");
pictureLayer = CreateDynamicLayer("pictureLayer");
// Layer style
if(IE)
{
darkLayer.style.filter = "alpha( style=0,opacity=" + DARK_LAYER_OPACITY * 100 +")";
}
else
{
darkLayer.style.opacity = DARK_LAYER_OPACITY;
}
centerLayer();
loadFilenames();
// find the current picture in the gallery
pictureIndex = indexOfFilename(picture.substring(picture.lastIndexOf("/") + 1));
// display loading as needed
pictureLayer.innerHTML = "<img src=\"" + LOADING_PIC + "\" />";
picObj = new Image();
picObj.onload = openEnlargedPicture;
picObj.src = picture;
}
}
function indexOfFilename(filename)
{
var found = false;
var index = -1;
for(var i = 0; i < pictures.length && !found; i++)
{
if(pictures[i][1] == filename)
{
found = true;
index = i;
}
}
return index;
}
/**
* This function opens an enlarged picture view using the given large size picture.
* @access public
* @param String picture A path to the picture.
*/
function openEnlargedPicture()
{
if(boolDoAgain == "Open")
{
// reset image event handler
picObj.onload = null;
// Get picture Max size
maxWidth = picObj.width + PICTURE_PADDING;
maxHeight = picObj.height + PICTURE_PADDING;
picRatio = maxWidth / maxHeight;
// Layer HTML content
var navigationHTML = "<div id=\"picture_navigation\" style=\"display: none;\"><img id=\"prevIcon\" src=\"" + prevIconObj.src + "\" onclick=\"showPreviousPicture();\"/><img id=\"nextIcon\" src=\"" + nextIconObj.src + "\" onclick=\"showNextPicture();\"/></div>";
var closeButtonHTML = "<div id=\"close_icon\" style=\"display: none;\"><img id=\"closeIcon\" src=\"" + closeIconObj.src + "\" onclick=\"closeEnlargedPicture();\" /></div>";
var pictureHTML = "<div id=\"large_picture_wrapper\" style=\"width: " + picObj.width + "px; height: " + picObj.height + "px; display: none;\"><img src=\"" + picObj.src + "\" id=\"PictureID\" /></div>";
var HTMLContent = closeButtonHTML + pictureHTML + navigationHTML;
pictureLayer.innerHTML = HTMLContent;
var picture_length = Math.sqrt(Math.pow(maxWidth, 2) + Math.pow(maxHeight, 2));
speedFactor = Math.pow(NUMBER_FRAMES, 3) / (6 * picture_length);
// start animation
boolDoAgain = setInterval("openingAnimation()", INTERVAL);
}
}
/**
* Creates a display of the status showing the current animation speed.
*/
function closeEnlargedPicture()
{
if(boolDoAgain == "Close")
{
document.getElementById("pictureLayer").innerHTML = "";
step = 5;
boolDoAgain = setInterval("closingAnimation()", INTERVAL);
}
}
/**
* Takes care of the animation side of opening an enlarged picture. This function will be called over
* and over again by a timer function to change the scene.
* @access private
*/
function openingAnimation()
{
pictureLayer.style.width = Math.round(width) + unitPostfix;
pictureLayer.style.height = Math.round(height) + unitPostfix;
centerLayer();
// check if we finished opening the layer
if(animation_time == NUMBER_FRAMES)
{
// yes, stop the opening prosses
clearInterval(boolDoAgain);
// make sure we have the exact height and width we wanted
pictureLayer.style.width = maxWidth + unitPostfix;
pictureLayer.style.height = maxHeight + unitPostfix;
document.getElementById("large_picture_wrapper").style.display = "block";
document.getElementById("picture_navigation").style.display = "block";
document.getElementById("close_icon").style.display = "block";
document.getElementById("close_icon").onclick = closeEnlargedPicture;
speed = 0;
animation_time = 0;
// html content to add
var HTMLContent = "<p class=\"picture_size\">" + (maxHeight - PICTURE_PADDING) + "X" + (maxWidth - PICTURE_PADDING) + "</p>";
pictureLayer.innerHTML += HTMLContent;
boolDoAgain = "Close";
}
else
{
// No, continue uncovering the rest of the layer
var length = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
animation_time += 1;
speed = Math.round(findSpeed(animation_time));
length += speed;
height = length / Math.sqrt(Math.pow(picRatio, 2) + 1);
width = height * picRatio;
}
}
/**
* Just like opening animation, but just the opposite effect. Function is called by a timer to
* animate the closing of the picture in enlarged view mode.
* @private
*/
function closingAnimation()
{
pictureLayer.style.width = width + unitPostfix;
pictureLayer.style.height = height + unitPostfix;
centerLayer();
// check if we finished opening the layer
if(animation_time == NUMBER_FRAMES)
{
// yes, stop the opening prosses
clearInterval(boolDoAgain);
destroyEnlargedPicture();
}
else
{
// No, continue folding the layer
var length = Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2));
animation_time += 1;
speed = Math.round(findSpeed(animation_time));
length -= speed;
height = length / Math.sqrt(Math.pow(picRatio, 2) + 1);
width = height * picRatio;
}
}
/**
* Cleans up after we are done with the enlarged view mode of that picture.
* @return
*/
function destroyEnlargedPicture()
{
DestroyDynamicLayer("pictureLayer");
DestroyDynamicLayer("darkLayer");
animation_time = 0;
speed = 0;
boolDoAgain = "Open";
}
/**
* Centers the picture layer to the middle of the page (document)
*/
function centerLayer()
{
var top;
var left;
// reset position to stay in the center of the page
top = (getDocumentHeight() / 2) - (height / 2);
left = (getDocumentWidth() / 2) - (width / 2);
if(left < 0)
left = 0;
if(top < 0)
top = 0;
pictureLayer.style.left = Math.round(left) + unitPostfix;
pictureLayer.style.top = Math.round(top) + unitPostfix;
}
/**
* Finds the speed at the given time.
* note: speedFactor most be already set globally.
* @param int frameNum The frame number
* @return double The speed.
*/
function findSpeed(frameNum)
{
// update matamatical variables speed formula is S = -t^2 + t
return (1 / speedFactor) * ((-1 * Math.pow(frameNum, 2)) + NUMBER_FRAMES * frameNum);
}
/**
* Loads the file names of the images so we can go forward and backward.
* @access private
* @return
*/
function loadFilenames()
{
var xmlDoc = xmlLoadFileParser("pics/images.xml");
// raw data
var filenameNodes = xmlDoc.getElementsByTagName("filename");
var dateNodes = xmlDoc.getElementsByTagName("date");
// create a table with the following fields -- date, filename -- using a two dimensional array.
for(var i = 0; i < filenameNodes.length && i < dateNodes.length; i++)
{
pictures.push(new Array(dateNodes[i].firstChild.nodeValue, filenameNodes[i].firstChild.nodeValue));
}
pictures.sort(sortByDate)
}
/**
* Sorts two records passed as 1-D arrays. The date MUST be the first value in the array.
* @param Array record1 The first record.
* @param Array record2 The second record.
*/
function sortByDate(record1, record2)
{
return compareDates(record1[0], record2[0]);
}
/**
* Compares 2 dates returning a negative number if the first date is smaller than the second one,
* a positive number if the first date is greater than the second date, and zero if the dates are equal.
* @param String strDate1 The first date. Format: "yyyy-mm-dd".
* @param String strDate2 The second date. Format: "yyyy-mm-dd".
* @access private.
* @return
*/
function compareDates(strDate1, strDate2)
{
var splitDate1 = strDate1.split("-");
var splitDate2 = strDate2.split("-");
var date1 = new Date(splitDate1[0], splitDate1[1] - 1, splitDate1[2] - 1);
var date2 = new Date(splitDate2[0], splitDate2[1] - 1, splitDate2[2] - 1);
return date1.valueOf() - date2.valueOf();
}
function showNextPicture()
{
destroyEnlargedPicture();
viewEnlarged(imagesDir + "/" + pictures[pictureIndex + 1][1]);
}
function showPreviousPicture()
{
destroyEnlargedPicture();
viewEnlarged(imagesDir + "/" + pictures[pictureIndex - 1][1]);
}
This post has been edited by Mike007: 27 December 2008 - 02:15 PM

New Topic/Question
Reply



MultiQuote





|