Jump to content

function refuses to be called more than once...


bluebomber

Recommended Posts

I've spent most of the day clearing up some very messy HTML, CSS and javascript on one of my website, and this evening have found a problem that's baffling me.The website in question is here : http://www.nihon35.com/test/Most of the sites content is controlled by using javascript to change the "display" property of various different DIV layers, today I've written a very basic javascript image preloader to make things a bit more efficient (on the old version I was simply piling 50 images into a hidden DIV but it was less than ideal) - now when the user clicks on an area of the site that contains an image thumbnail gallery - a function is automatically called which begins to preload the images relevant to that page.The js file that contains the preloader functions is here:http://www.nihon35.com/test/preloader.jsThe problem I now have, is that any button on the website (for example the Tokyo, Kansai, West buttons on the bottom left of the main page) which indirectly trigger a preloader.js function will not work on any second or subsequent attempt to click it.The best way to test this, is to simply click on any one of those buttons (taking you to the thumbnail gallery) - return to the main menu and then re-attempt to go back to that page - it won't work.The problem is clearly related to the preloader file - but I've no idea what.Any ideas?

Link to comment
Share on other sites

I've uploaded a version of the site with the DIV display functions and preload functions in the same js file - it can be found here:http://www.nihon35.com/test2/The .js file is here:http://www.nihon35.com/test2/layerswitching.jsCuriously - now none of the buttons on the site work at all - even when it first loads, I'm guessing there's just something wrong with the preload code that's causing it to fall over?

Link to comment
Share on other sites

Ingolme - I've tried the site in IE8, Chrome, Safari and Firefox 4 beta and every browser has the same problem, you can go into any of the catagories - but once you come out - you can't go back in.If this clue helps - I've noticed that the actual image preloading code does not work on Firefox (when you click on a thumbnail you can see the image is being loaded for the first time) - but the preloading does work on the other 3 browsers.

It seems to work fine for me. Which browser have you detected the problem in?
Link to comment
Share on other sites

Your new test page does have some mistakes:You're missing an opening brace ({) at the end of this line:

for(i=0; i<=15; i++)

The functions tokyo() kansai() and west() aren't defined, according to the error console.

Link to comment
Share on other sites

Hello, you are quite right about the opening brackets on the for loops, I've fixed these locally but the problem persists.I can't imagine why those functions are seen as undefined - the answer is probably just staring me right in the face but I'm puzzled.

Your new test page does have some mistakes:You're missing an opening brace ({) at the end of this line:
for(i=0; i<=15; i++)

The functions tokyo() kansai() and west() aren't defined, according to the error console.

Link to comment
Share on other sites

I found the mistake:

function tokyopreload(){tokyo_image_object = new Image();tokyo = new Array();

You're overwriting the global "tokyo" variable here. Use the var keyword to make the variable local instead:

var tokyo = new Array();

Link to comment
Share on other sites

Ok this works, thanks very much - but I must confess I'm confused as to what this problem actually was - overwriting the global tokyo variable?Can you explain?

I found the mistake:
function tokyopreload(){tokyo_image_object = new Image();tokyo = new Array();

You're overwriting the global "tokyo" variable here. Use the var keyword to make the variable local instead:

var tokyo = new Array();

Link to comment
Share on other sites

Ok this works, thanks very much - but I must confess I'm confused as to what this problem actually was - overwriting the global tokyo variable?Can you explain?
In Javascript, all functions are variables.A global variable is%2
Link to comment
Share on other sites

I knew about global variables but must admit didn't realise functions were also variables.Is your example supposed to have two functions called "test" ?

In Javascript, all functions are variables.A global variable is one that's created outside of any functions. If you want to modify a global variable from inside a function you can just use the variable's name without declaring it first. If you want a variable of the same name inside the function then you have to declare it with the var keyword.
var a = "Hello";function test() {  var a = 5;}function test() {  a = 5;}test();alert(a); // Shows "Hello"test2();alert(a); // Shows 5

Link to comment
Share on other sites

I knew about global variables but must admit didn't realise functions were also variables.Is your example supposed to have two functions called "test" ?
No, I made a mistake. The second one should be "test2". I'll be editing my post for clarity.
Link to comment
Share on other sites

That most likely is because you keep changing the src of the same image object before it has a change to load. You have to make one image object for each image to preload.

loadImages = new Array();var i = 0;for(i=0; i<=15; i++){   loadImages[i] = new Image();  loadImages[i].src = tokyo[i];}

I suggest properly indenting your code. It took me a while to see the closing brace on your for() loop.

Link to comment
Share on other sites

hmm.. I can totally see the logic in what you're saying, I quickly modified one of my preload functions to use the technique you've suggested, however like my current method, it works in Chrome, IE and Safari but still not in Firefox (4).

That most likely is because you keep changing the src of the same image object before it has a change to load. You have to make one image object for each image to preload.
loadImages = new Array();var i = 0;for(i=0; i<=15; i++){   loadImages[i] = new Image();  loadImages[i].src = tokyo[i];}

I suggest properly indenting your code. It took me a while to see the closing brace on your for() loop.

Link to comment
Share on other sites

Hmm, the other thing is that you're loading the images immediately after they start preloading. Program execution doesn't pause while an image object is loading, so if you start preloading an image and then immediately display it, it may not be completely loaded yet.Normally, preloading is done before the page starts loading and it's done for images that aren't going to be displayed until an action is done.

Link to comment
Share on other sites

Because the site has the best part of 60 images now, I've moved away from preloading them all in bulk at the start because it was too slow and chaotic.Instead, I preload just the relevant batch of images (in groups of 16 max) when you visit each thumbnail page.I understand what your saying - ie, if I click on a thumbnail page and immediately jump to image 16 you will still have to wait - but the delay is short and does not worry me - the fact of the matter though is that Firefox isn't preloading these images at all.With any other browser, I can select a thumbnail page and within 4-5 seconds all the images will be there, you can clear your cache and try it yourself - go to the Tokyo page, and wait just a few moments and all images will be there and fade in smoothly when clicked.In Firefox, I can sit on a thumbnail page for 5 minutes but it won't matter - only when I click a thumbnail will I then see the browser attempt to load the image, so there is something about that javascript that simply isn't Firefox compatible.In truth, it doesn't bother me that there's a small delay when clicking on thumbnails for one browser, but what does really concern me is that the left \ right arrow buttons which cycle through images (once you are in the "viewer") behave particularly badly if images have not been preloaded - you'll click on one and the image will fade out only to fade the same one back again (because the image it looked for is still loading) and then you'll see the new image suddenly pop into view - this is very confusing for the user - and again for some reason only works in Firefox.Really struggling with this.

Link to comment
Share on other sites

I think I know what's happening. Firebug is telling me that the requests for the images are being aborted.This is most likely because variables on the local scope are destroyed as soon as a function stops running. You might want to try putting it on a global scope instead.

// Global variablevar TokyoPreloadImages = new Array();function tokyopreload(){  ...  var i;  for(i=0; i<=tokyo.length; i++){ 	TokyoPreloadImages[i] = new Image();	TokyoPreloadImages[i].src = tokyo[i];  }}

Link to comment
Share on other sites

hmm - I've just tried taking the array out of the function and into a global space (tested locally) but now the button no longer works when you click on it so you are not taken to the thumbnail page in the first place - code looked like this:var tokyo = new Array();tokyo[0]="phototokyo/1.jpg"tokyo[1]="phototokyo/2.jpg"tokyo[2]="phototokyo/3.jpg"...function tokyopreload(){ var i = 0; for(i=0; i<=15; i++){ tokyo = new Image(); tokyo.src = tokyo;} }

I think I know what's happening. Firebug is telling me that the requests for the images are being aborted.This is most likely because variables on the local scope are destroyed as soon as a function stops running. You might want to try putting it on a global scope instead.
// Global variablevar TokyoPreloadImages = new Array();function tokyopreload(){  ...  var i;  for(i=0; i<=tokyo.length; i++){ 	TokyoPreloadImages[i] = new Image();	TokyoPreloadImages[i].src = tokyo[i];  }}

Link to comment
Share on other sites

hmm - I've just tried taking the array out of the function and into a global space (tested locally) but now the button no longer works when you click on it so you are not taken to the thumbnail page in the first place - code looked like this:var tokyo = new Array();tokyo[0]="phototokyo/1.jpg"tokyo[1]="phototokyo/2.jpg"tokyo[2]="phototokyo/3.jpg"...function tokyopreload(){ var i = 0; for(i=0; i<=15; i++){ tokyo = new Image(); tokyo.src = tokyo;} }
Well, you're overwriting the tokyo() function again. But you don't need to take that array out of the function.Look at my code more carefully. What you need is an array of Image() objects that are in the global scope.
// Global variablevar TokyoPreloadImages = new Array();function tokyopreload(){  var tokyo = new Array();  tokyo[0]="phototokyo/1.jpg"  tokyo[1]="phototokyo/2.jpg"  tokyo[2]="phototokyo/3.jpg"  var i;  for(i=0; i<=tokyo.length; i++) {	// Add a new Image() object to the array in the global scope	TokyoPreloadImages[i] = new Image();	TokyoPreloadImages[i].src = tokyo[i];  }}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...