如何通过JavaScript加载图像时显示微调器

时间:2008-09-09 07:33:37

标签: javascript jquery dom

我目前正在开发一个Web应用程序,它有一个显示单个图表(.png图像)的页面。在这个页面的另一部分,有一组链接,当点击时,整个页面重新加载,看起来与之前完全相同,除了页面中间的图表。

我想要做的是在页面上单击链接时,只更改页面上的图表。这将大大加快速度,因为页面大约100kb大,并且真的不想重新加载整个页面只是为了显示它。

我一直在通过JavaScript进行此操作,到目前为止,使用以下代码

document.getElementById('chart').src = '/charts/10.png';

问题是当用户点击链接时,图表更改可能需要几秒钟。这使得用户认为他们的点击没有做任何事情,或者系统响应缓慢。

我想要发生的是显示一个微调/ throbber /状态指示器,代替图像在加载时的位置,所以当用户点击链接时,他们知道至少系统已经接受了他们的输入并且正在做关于它的事情。

我已经尝试了一些建议,即使使用psudo超时来显示微调器,然后再回到图像。

我有一个很好的建议是使用以下

<img src="/charts/10.png" lowsrc="/spinner.gif"/>

哪个是理想的,除了微调器显着小于正在显示的图表。

还有其他想法吗?

13 个答案:

答案 0 :(得分:41)

我已经使用过这样的东西来预加载图像,然后在图像加载完成后自动回调我的javascript。您希望在设置回调之前检查完成,因为图像可能已经被缓存,并且可能无法调用您的回调。

function PreloadImage(imgSrc, callback){
  var objImagePreloader = new Image();

  objImagePreloader.src = imgSrc;
  if(objImagePreloader.complete){
    callback();
    objImagePreloader.onload=function(){};
  }
  else{
    objImagePreloader.onload = function() {
      callback();
      //    clear onLoad, IE behaves irratically with animated gifs otherwise
      objImagePreloader.onload=function(){};
    }
  }
}

答案 1 :(得分:21)

您可以显示提供optical illusion of a spinny-wheel, like these的静态图片。

答案 2 :(得分:11)

使用 jQuery load()方法,可以在加载图片后立即执行操作:

$('img.example').load(function() {
  $('#spinner').fadeOut();
});

请参阅:http://api.jquery.com/load-event/

答案 3 :(得分:10)

使用setTimeout()函数(More info)的强大功能 - 这允许您设置一个定时器以在将来触发函数调用,并调用它阻止执行当前/其他功能(async。)。

将包含微调器的div放在图表图像上方,并将其css显示属性设置为无:

<div>&nbsp;<img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>

当隐藏微调器时,停止div折叠。没有它,当您切换微调器的显示时,您的布局将“抽搐”

function chartOnClick() {
  //How long to show the spinner for in ms (eg 3 seconds)
  var spinnerShowTime = 3000

  //Show the spinner
  document.getElementById('spinnerImg').style.display = "";

  //Change the chart src
  document.getElementById('chart').src = '/charts/10.png';

  //Set the timeout on the spinner
  setTimeout("hideSpinner()", spinnerShowTime);
}

function hideSpinner() {
  document.getElementById('spinnerImg').style.display = "none";
}

答案 4 :(得分:3)

使用CSS将加载动画设置为图像容器的居中背景图像。

然后在加载新的大图像时,首先将src设置为预加载的透明1像素gif。

e.g。

document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';

当加载large_image.jpg时,背景将通过1pix透明gif显示。

答案 5 :(得分:3)

根据Ed的回答,我更愿意看到类似的内容:

function PreLoadImage( srcURL, callback, errorCallback ) {
     var thePic = new Image();

     thePic.onload = function() {
          callback();
          thePic.onload = function(){};
     }

     thePic.onerror = function() {
          errorCallback();
     }
     thePic.src = srcURL;
}

您的回调可以在适当的位置显示图像并处理/隐藏微调器,而errorCallback可以防止您的页面“乱弹”。所有事件驱动,没有定时器或轮询,而且您不必添加额外的if语句来检查图像是否在您设置事件的位置完成加载 - 因为它们预先设置它们将触发,无论如何快速加载图像。

答案 6 :(得分:3)

前段时间我写了一个jQuery插件,自动处理显示微调器http://denysonique.github.com/imgPreload/

查看其源代码可以帮助您检测何时显示微调器并将其显示在加载图像的中心。

答案 7 :(得分:2)

我喜欢@duddle的jquery方法,但发现并不总是调用load()(例如在IE中从缓存中检索图像时)。我改用这个版本:

$('img.example').one('load', function() {
  $('#spinner').remove();
}).each(function() {
  if(this.complete) {
    $(this).trigger('load');
  }
});

如果已经完成加载,则最多调用一次加载。

答案 8 :(得分:1)

将微调器放在与图表大小相同的div中,您知道高度和宽度,这样您就可以使用相对定位来正确居中。

答案 9 :(得分:1)

除了lowsrc选项之外,我还在background-image的容器上使用了img

答案 10 :(得分:1)

请注意,如果图像src不存在,也会调用回调函数(http 404错误)。为避免这种情况,您可以检查图像的宽度,例如:

if(this.width == 0) return false;

答案 11 :(得分:-1)

@ iAn的解决方案对我来说很好看。我唯一要改变的是使用setTimeout而不是使用setTimeout,我会尝试并挂钩图像的'Load'事件。这样,如果图像下载时间超过3秒,您仍将获得微调器。

另一方面,如果下载时间较短,您将获得不到3秒的微调器。

答案 12 :(得分:-1)

我会添加一些随机数字以避免浏览器缓存。