Javascript块脚本执行
Posted
技术标签:
【中文标题】Javascript块脚本执行【英文标题】:Javascript block script execution 【发布时间】:2010-02-17 14:26:40 【问题描述】:我需要这样做:
执行一段代码 开始加载图片并阻止脚本执行 加载图像后恢复执行 执行其余代码我知道最简单的方法是在图像的 onload 事件上分配一个函数,然后执行函数中的其余代码,但如果可能的话,我希望有一个“线性”行为阻止脚本执行然后恢复它。 那么,有没有跨浏览器的方式来做到这一点?
【问题讨论】:
【参考方案1】:阻止脚本执行的唯一方法是使用循环,这也会锁定大多数浏览器并阻止与您的网页进行任何交互。
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
话虽如此,我认为您应该考虑在不锁定浏览器的情况下实现目标的方法。
【讨论】:
我同意这是一种不好的方式,但我也认为这是唯一的方式。也许我可以让用户在加载图像时选择阻止脚本执行和调用加载函数。 @mck89:我很难相信这是唯一的方法。老实说,我在 javascript 中从未遇到过需要锁定脚本的情况。总有一种方法(例如临时覆盖函数)可以异步执行操作。毕竟,您可以控制页面上的脚本。也许您可以发布另一个问题来更详细地了解您的问题? @mck89:complete
属性适用于 Gecko 和 IE,并且可能也适用于其他浏览器。如果您坚持阻止脚本执行,请参阅我的更新。
是的,我想我会用这样的东西谢谢你的帮助。【参考方案2】:
如果您不介意进行预处理步骤,请尝试Narrative Javascript,您可以这样做
image.onload = new EventNotifier();
image.onload.wait->();
【讨论】:
这是一个很棒的项目,但我正在尝试用纯 javascript 构建一个简单的应用程序......而且我对 Java 一无所知:) @mck89:经过预处理后,您将获得纯 Javascript。 是的,我知道,但我更喜欢只使用 javascript 据我所知,Narrative JavaScript 所做的只是为您创建必要的回调。它不会停止脚本执行(因为脚本的其他部分仍然可以运行)。 @Andy:所以你认为 OP 想要一个检查循环 (while(!image.loaded)
)?【参考方案3】:
此建议并非您所要求的,但我将其作为可能的替代方案提供。
使用您要使用的背景图像创建一个 CSS 类。当您的应用程序启动时,将此 CSS 类分配给一个 DIV,该 DIV 要么隐藏在站点外,要么按零像素调整为零。这将确保从服务器加载图像。当你想加载图像时(上面的第二步),使用你创建的 CSS 类;这将很快发生。也许足够快,您无需阻止后续代码执行?
【讨论】:
是的,这可能是一个很好的图像预加载方法,但我没有在应用程序开始时加载图像。 我明白,但是如果您创建了一个带有 background-image 属性的 CSS 类,并将该类分配给一个虚拟 DIV,您将在应用程序的开头加载图像。【参考方案4】:我不会尝试完全阻止脚本执行,因为这可能会使浏览器变慢,甚至会提醒用户脚本执行时间过长。
您可以做的是通过使用事件来“线性化”您的代码来完成工作。您需要为函数添加超时时间,因为图像可能永远不会加载。
例子:
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;
【讨论】:
您确定可以使用 setTimeout 停止执行吗? 这不会停止代码执行,它允许您等到图像加载完成后再进行任何工作。通过将剩余代码移动到 finishWork 函数中,您“停止”执行自己的代码。【参考方案5】:您可以使用 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 标头提供。否则,它的行为在不同的浏览器中可能会有所不同。
【讨论】:
以上是关于Javascript块脚本执行的主要内容,如果未能解决你的问题,请参考以下文章