5

我需要做这样的事情:

  • 执行一段代码
  • 开始加载图像并阻止脚本执行
  • 加载图像后恢复执行
  • 执行剩下的代码

我知道最简单的方法是在图像的 onload 事件上分配一个函数,然后执行函数中的其余代码,但是如果可能的话,我希望有一个“线性”行为阻止脚本执行然后恢复它。那么,有没有一种跨浏览器的方法来做到这一点?

4

5 回答 5

3

阻止脚本执行的唯一方法是使用循环,这也会锁定大多数浏览器并阻止与您的网页进行任何交互。

Firefox、Chrome、Safari、Opera 和 IE支持该complete属性,最终在 HTML5 中标准化。这意味着您可以使用while循环来停止脚本执行,直到图像完成下载。

var img = new Image();
img.src = "/myImage.jpg";
document.body.appendChild(img);
while (!img.complete) 
{
    // do nothing...
}

// script continues after image load

话虽如此,我认为您应该考虑在不锁定浏览器的情况下实现目标的方法。

于 2010-02-17T14:35:26.643 回答
1

如果您不介意进行预处理步骤,请尝试Narrative Javascript,您可以

image.onload = new EventNotifier();
image.onload.wait->();
于 2010-02-17T14:33:42.933 回答
1

这个建议并不完全符合您的要求,但我将其作为可能的替代方案提供。

使用您要使用的背景图像创建一个 CSS 类。当您的应用程序启动时,将此 CSS 类分配给一个 DIV,该 DIV 要么隐藏在站点外,要么按零像素调整为零。这将确保从服务器加载图像。当你想加载图片时(上面的第二步),使用你创建的 CSS 类;这将很快发生。也许足够快以至于您不需要阻止后续代码执行?

于 2010-02-17T14:41:01.343 回答
1

我不会尝试完全阻止脚本执行,因为这可能会使浏览器变慢,甚至会提醒用户脚本执行时间过长。

您可以做的是通过使用事件来完成工作来“线性化”您的代码。您需要为该功能添加一个超时时间,因为图像可能永远不会加载。

例子:

var _img = null; 
var _imgDelay = 0;
var _finished = false;

function startWork(){
   _img = document.createElement('img');
   _img.onload = onImgLoaded;
   _img.src = 'yourimg.png';

   // append img tag to parent element here

   // this is a time out function in case the img never loads,
   // or the onload event never fires (which can happen in some browsers) 
   imgTimeout();   
}

function imgTimeout(){
   if (_img.complete){
      // img is really done loading
      finishWork();
   }
   else{
      // calls recursively waiting for the img to load
      // increasing the wait time with each call, up to 12s
      _imgDelay += 3000;

      if (_imgDelay <= 12000){ // waits up to 30 seconds
         setTimeout(imgTimeout, _imgDelay);
      }
      else{
         // img never loaded, recover here.
      }
   }
}

function onImgLoaded(){
   finishWork();
}

function finishWork(){
   if (!_finished){
      // continue here
      _finished = true;
   }
}
于 2010-02-17T14:57:57.003 回答
1

您可以使用 xmlhttprequest 并使用同步模式。

var url = "image.php?sleep=3";
var img = new Image;
var sjax = new XMLHttpRequest();
img.src = url;
sjax.open("GET", url, false);
sjax.send(null);
alert(img.complete);

这里的技巧是我们两次加载相同的图像,首先使用Image对象,然后在同步模式下使用 ajax。Image不需要该对象,我只是假设这就是您要加载它的方式。但关键是,如果 ajax 完成,那么图像将被完全下载到浏览器的缓存中。因此,图像也可供Image对象使用。

这确实假设图像使用缓存友好的 http 标头提供。否则,它的行为在不同的浏览器中可能会有所不同。

于 2010-02-17T15:48:56.970 回答