使用jQuery BlockUI时,如何等待iframe加载完成后再解除页面阻塞?
解决iframe加载完成后再解除BlockUI阻塞的问题
嘿,这个问题太常见了——异步操作的“不等就走”特性确实容易让新手头疼😎。你现在的问题核心是:设置iframe的src后,浏览器会异步加载这个资源,而你的同步代码会直接往下执行,所以硬写的2秒延迟完全是碰运气,要么加载快了白等,要么加载慢了提前解除阻塞,体验很差。
正确的思路:监听iframe的load事件
我们需要让代码“等待”iframe真正加载完成(不管成功还是失败),再执行解除阻塞的操作。具体步骤如下:
- 移除原来硬编码的
setTimeout($.unblockUI, 2000),这是不可靠的。 - 在设置iframe的
src之前,给它绑定一次性的load事件(用.one()避免重复触发)。 - 同时监听
error事件,防止iframe加载失败时页面一直被阻塞。 - 如果有多个iframe需要等待,可以用
Promise.all来统一处理所有加载完成的信号。
修改后的完整代码
function reload_data() { // 1. 阻塞页面 $.blockUI({ message: $('#spinner_div'), css: { top: '50%', left:'50%', border:'none'} }); // 2. 清除内容 $('#my_kpi').text(''); // 清空锚点内容 const $iframe = $('#inf_prioridad_estado iframe'); $iframe.attr('src',''); // 清空iframe的src // 3. 准备监听iframe加载完成事件 // 用.one()确保只触发一次,避免多次调用reload_data时重复绑定 $iframe.one('load', function() { // iframe加载成功后解除阻塞 $.unblockUI(); console.log('iframe加载完成,已解除阻塞'); }).one('error', function() { // 即使iframe加载失败,也要解除阻塞,避免页面卡死 $.unblockUI(); console.log('iframe加载失败,已解除阻塞'); }); // 4. 加载内容 $('#my_kpi').text('loaded'); // 设置锚点内容 $iframe.attr('src','foo.php'); // 触发iframe加载 }
额外说明:多iframe场景
如果你的页面需要同时加载多个iframe,等所有都加载完再解除阻塞,可以用Promise封装每个iframe的加载事件:
function waitForIframeLoad($iframe) { return new Promise((resolve, reject) => { $iframe.one('load', resolve).one('error', reject); }); } function reload_data() { $.blockUI({/* 配置不变 */}); // 清除内容... const $iframe1 = $('#iframe1'); const $iframe2 = $('#iframe2'); // 绑定事件后设置src $iframe1.attr('src', 'page1.php'); $iframe2.attr('src', 'page2.php'); // 等待所有iframe加载完成(成功或失败) Promise.allSettled([waitForIframeLoad($iframe1), waitForIframeLoad($iframe2)]) .then(() => { $.unblockUI(); console.log('所有iframe加载完成/失败,已解除阻塞'); }); }
这样处理就完全贴合你的需求了——只有当iframe真正加载完成(或失败)时,才会解除页面阻塞,再也不用靠猜延迟时间啦!
内容的提问来源于stack exchange,提问作者glezo
相关产品推荐
相关产品推荐

