Javascript 块脚本执行

发布于 2024-08-22 02:03:17 字数 207 浏览 4 评论 0原文

我需要做这样的事情:

  • 执行一段代码
  • 开始加载图像并阻止脚本执行
  • 当加载图像时恢复执行 执行
  • 其余代码

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

I need to do something like this:

  • Execute a piece of code
  • Start to load an image and block the script execution
  • When the image is loaded resume the execution
  • Execute the rest of the code

I know that the simplest way is to assign a function on the onload event of the image and then execute the rest of the code in the function, but if it's possible i want to have a "linear" behaviour blocking the script execution and then resume it.
So, is there a cross-browser way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏日浅笑〃 2024-08-29 02:03:18

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

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

例子:

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;
   }
}

I wouldn't try to block script execution completely, as that could make the browser slow down, or even alert the user that a script is taking too long to execute.

What you can do is 'linearize' your code by using events to finish work. You will need to add a time out to the function, as the image may never load.

Example:

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;
   }
}
霞映澄塘 2024-08-29 02:03:18

您可以使用 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 标头提供。否则,它的行为在不同的浏览器中可能会有所不同。

You can use xmlhttprequest and use synchronous mode.

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);

The trick here is we load the same image twice, first by using the Image object, and also by using ajax in synchronous mode. The Image object isn't needed, I just assumed that's how you want to load it. The key though is that if ajax completes, then the image will be fully downloaded an in the browser's cache. As such, the image will also be available for use by the Image object.

This does assume that the image is served with cache friendly http headers. Otherwise, it's behavior might vary in different browsers.

江湖正好 2024-08-29 02:03:17

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

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

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

The only way to block script execution is to use a loop, which will also lock up most browsers and prevent any interaction with your web page.

Firefox, Chrome, Safari, Opera and IE all support the complete property, which was finally standardised in HTML5. This means you can use a while loop to halt script execution until the image has finished downloading.

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

// script continues after image load

That being said, I think you should look at ways of achieving your goal without locking up the browser.

再见回来 2024-08-29 02:03:17

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

image.onload = new EventNotifier();
image.onload.wait->();

If you don't mind having a preprocessing step, try Narrative Javascript, which you can

image.onload = new EventNotifier();
image.onload.wait->();
节枝 2024-08-29 02:03:17

这个建议并不完全是你所要求的,但我提供它作为一个可能的替代方案。

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

This suggestion is not exactly what you asked for, but I offer it as a possible alternative.

Create a CSS class with the background-image you want to use. When your app starts, assign this CSS class to a DIV that is either hidden out of site or sized to zero by zero pixels. This will ensure the image is loaded from the server. When you want to load the image (step two above), use the CSS class you create; this will happen quickly. Maybe quickly enough that you need not block the subsequent code execution?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文