<p>I'm currently working on a web application which has a page which displays a single chart (a .png image).  On another part of this page there are a set of links which, when clicked, the entire page reloads and looks exactly the same as before except for the chart in the middle of the page.</p>

<p>What I want to do is when a link is clicked on a page just the chart on the page is changed.  This will speed things up tremendously as the page is roughly 100kb large, and don't really want to reload the entire page just to display this.  </p>

<p>I've been doing this via JavaScript, which works so far, using the following code</p>

<pre><code>document.getElementById('chart').src = '/charts/10.png';
</code></pre>

<p>The problem is that when the user clicks on the link, it may take a couple of seconds before the chart changes.  This makes the user think that their click hasn't done anything, or that the system is slow to respond.</p>

<p>What I want to happen is display a spinner / throbber / status indicator, in place of where the image is while it is loading, so when the user clicks the link they know at least the system has taken their input and is doing something about it.  </p>

<p>I've tried a few suggestions, even using a psudo time out to show a spinner, and then flick back to the image.  </p>

<p>A good suggestion I've had is to use the following</p>

<pre><code>&lt;img src="/charts/10.png" lowsrc="/spinner.gif"/&gt;
</code></pre>

<p>Which would be ideal, except the spinner is significantly smaller than the chart which is being displayed.</p>

<p>Any other ideas?</p>

[{'answer_id': 51360, 'author': 'Mauro', 'author_id': 2208, 'author_profile': 'https://Stackoverflow.com/users/2208', 'pm_score': 1, 'selected': False, 'text': '<p>put the spinner in a div the same size as the chart, you know the height and width so you can use relative positioning to center it correctly.</p>\n'}, {'answer_id': 51368, 'author': 'Ian', 'author_id': 4396, 'author_profile': 'https://Stackoverflow.com/users/4396', 'pm_score': 3, 'selected': False, 'text': '<p>Use the power of the setTimeout() function (<a href="http://www.w3schools.com/js/js_timing.asp" rel="nofollow noreferrer">More info</a>) - this allows you set a timer to trigger a function call in the future, and calling it <strong>won\'t</strong> block execution of the current / other functions (async.).</p>\n\n<p>Position a div containing the spinner above the chart image, with it\'s css display attribute set to none:</p>\n\n<pre><code>&lt;div&gt;&amp;nbsp;&lt;img src="spinner.gif" id="spinnerImg" style="display: none;" /&gt;&lt;/div&gt;\n</code></pre>\n\n<p><em>The nbsp stop the div collapsing when the spinner is hidden. Without it, when you toggle display of the spinner, your layout will "twitch"</em></p>\n\n<pre><code>function chartOnClick() {\n  //How long to show the spinner for in ms (eg 3 seconds)\n  var spinnerShowTime = 3000\n\n  //Show the spinner\n  document.getElementById(\'spinnerImg\').style.display = "";\n\n  //Change the chart src\n  document.getElementById(\'chart\').src = \'/charts/10.png\';\n\n  //Set the timeout on the spinner\n  setTimeout("hideSpinner()", spinnerShowTime);\n}\n\nfunction hideSpinner() {\n  document.getElementById(\'spinnerImg\').style.display = "none";\n}\n</code></pre>\n'}, {'answer_id': 51384, 'author': 'Chris Roberts', 'author_id': 475, 'author_profile': 'https://Stackoverflow.com/users/475', 'pm_score': -1, 'selected': False, 'text': "<p>@iAn's solution looks good to me.  The only thing I'd change is instead of using setTimeout, I'd try and hook into the images 'Load' event.  This way, if the image takes longer than 3 seconds to download, you'll still get the spinner.</p>\n\n<p>On the other hand, if it takes less time to download, you'll get the spinner for less than 3 seconds.</p>\n"}, {'answer_id': 52597, 'author': 'Ed Haber', 'author_id': 2926, 'author_profile': 'https://Stackoverflow.com/users/2926', 'pm_score': 6, 'selected': True, 'text': "<p>I've used something like this to preload an image and then automatically call back to my javascript when the image is finished loading. You want to check complete before you setup the callback because the image may already be cached and it may not call your callback.</p>\n\n<pre><code>function PreloadImage(imgSrc, callback){\n  var objImagePreloader = new Image();\n\n  objImagePreloader.src = imgSrc;\n  if(objImagePreloader.complete){\n    callback();\n    objImagePreloader.onload=function(){};\n  }\n  else{\n    objImagePreloader.onload = function() {\n      callback();\n      //    clear onLoad, IE behaves irratically with animated gifs otherwise\n      objImagePreloader.onload=function(){};\n    }\n  }\n}\n</code></pre>\n"}, {'answer_id': 52605, 'author': 'JosephStyons', 'author_id': 672, 'author_profile': 'https://Stackoverflow.com/users/672', 'pm_score': 4, 'selected': False, 'text': '<p>You could show a static image that gives the <a href="http://www.ritsumei.ac.jp/~akitaoka/saishin-e.html" rel="noreferrer">optical illusion of a spinny-wheel, like these</a>.</p>\n'}, {'answer_id': 55265, 'author': 'travis', 'author_id': 1414, 'author_profile': 'https://Stackoverflow.com/users/1414', 'pm_score': 1, 'selected': False, 'text': "<p>Aside from the lowsrc option, I've also used a <code>background-image</code> on the <code>img</code>'s container.</p>\n"}, {'answer_id': 1459989, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 2, 'selected': False, 'text': "<p>Use CSS to set the loading animation as a centered background-image for the image's container.</p>\n\n<p>Then when loading the new large image, first set the src to a preloaded transparent 1 pixel gif.</p>\n\n<p>e.g.</p>\n\n<pre>\ndocument.getElementById('mainimg').src = '/images/1pix.gif';\ndocument.getElementById('mainimg').src = '/images/large_image.jpg';\n</pre>\n\n<p>While the large_image.jpg is loading, the background will show through the 1pix transparent gif.</p>\n"}, {'answer_id': 1674311, 'author': 'Svetoslav Marinov', 'author_id': 86771, 'author_profile': 'https://Stackoverflow.com/users/86771', 'pm_score': -1, 'selected': False, 'text': '<p>I would add some random digits to avoid the browser cache.</p>\n'}, {'answer_id': 2902494, 'author': '4AM', 'author_id': 206552, 'author_profile': 'https://Stackoverflow.com/users/206552', 'pm_score': 2, 'selected': False, 'text': '<p>Building on Ed\'s answer, I would prefer to see something like:</p>\n\n<pre><code>function PreLoadImage( srcURL, callback, errorCallback ) {\n     var thePic = new Image();\n\n     thePic.onload = function() {\n          callback();\n          thePic.onload = function(){};\n     }\n\n     thePic.onerror = function() {\n          errorCallback();\n     }\n     thePic.src = srcURL;\n}\n</code></pre>\n\n<p>Your callback can display the image in its proper place and dispose/hide of a spinner, and the errorCallback prevents your page from "beachballing". All event driven, no timers or polling, plus you don\'t have to add the additional if statements to check if the image completed loading while you where setting up your events - since they\'re set up beforehand they\'ll trigger regardless of how quickly the images loads.</p>\n'}, {'answer_id': 3083558, 'author': 'Christoph', 'author_id': 372034, 'author_profile': 'https://Stackoverflow.com/users/372034', 'pm_score': 1, 'selected': False, 'text': "<p>Be aware that the callback function is also called if the image src doesn't exist (http 404 error). To avoid this you can check the width of the image, like:</p>\n\n<pre><code>if(this.width == 0) return false;\n</code></pre>\n"}, {'answer_id': 5994193, 'author': 'crispy', 'author_id': 231529, 'author_profile': 'https://Stackoverflow.com/users/231529', 'pm_score': 4, 'selected': False, 'text': '<p>Using the <strong>load()</strong> method of <strong>jQuery</strong>, it is easily possible to do something as soon as an image is loaded:</p>\n\n<pre><code>$(\'img.example\').load(function() {\n  $(\'#spinner\').fadeOut();\n});\n</code></pre>\n\n<p>See: <a href="http://api.jquery.com/load-event/" rel="noreferrer">http://api.jquery.com/load-event/</a></p>\n'}, {'answer_id': 7624654, 'author': 'BC.', 'author_id': 54838, 'author_profile': 'https://Stackoverflow.com/users/54838', 'pm_score': 2, 'selected': False, 'text': "<p>I like @duddle's jquery method but find that load() isn't always called (such as when the image is retrieved from cache in IE). I use this version instead:</p>\n<pre><code>$('img.example').one('load', function() {\n  $('#spinner').remove();\n}).each(function() {\n  if(this.complete) {\n    $(this).trigger('load');\n  }\n});\n</code></pre>\n<p>This calls load at most one time and immediately if it's already completed loading.</p>\n"}, {'answer_id': 13538873, 'author': 'denysonique', 'author_id': 569061, 'author_profile': 'https://Stackoverflow.com/users/569061', 'pm_score': 2, 'selected': False, 'text': '<p>Some time ago I have written a jQuery plugin which handles displaying a spinner automatically <a href="http://denysonique.github.com/imgPreload/" rel="nofollow">http://denysonique.github.com/imgPreload/</a></p>\n\n<p>Looking in to its source code should help you with detecting when to display the spinner and with displaying it in the centre of the loaded image.</p>\n'}]
['https://Stackoverflow.com/questions/51352', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3847/']