You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保动态添加的JS加载完成后再渲染HTML Body?

解决动态JS加载完成前阻止Body渲染的问题

我来帮你搞定这个难题——你遇到的核心问题是:动态加载JS的异步过程和浏览器解析渲染Body的时序冲突了,导致依赖这些JS的内容还没准备好就被渲染。下面是几个实用且优雅的解决方案:

方案1:初始隐藏Body,待所有动态JS加载完成后显示

这是最简单直接的方法,先让Body一开始处于隐藏状态,等所有依赖脚本加载完成后再显示,避免用户看到未正常渲染的内容。

步骤:

  1. 修改Body标签,添加初始隐藏样式:
<body class="dx-viewport" style="display: none;">
  1. 优化你的AJAX脚本,跟踪所有动态加载的JS的状态,等全部加载完成后再显示Body并执行初始化逻辑:
$.ajax({
  type: "Get",
  url: '@Url.Action("GetLocalisationFiles", "Localisation")',
  success: function (response) {
    // 用Promise数组跟踪每个脚本的加载状态
    const scriptLoadPromises = [];
    
    for (var file in response) {
      var scriptName = response[file];
      // 为每个脚本创建一个Promise,加载完成后resolve
      scriptLoadPromises.push(new Promise((resolve, reject) => {
        let myScript = document.createElement("script");
        myScript.src = scriptName;
        // 脚本加载成功
        myScript.onload = () => {
          console.log(`Loaded script: ${scriptName}`);
          resolve();
        };
        // 处理脚本加载失败的情况
        myScript.onerror = () => reject(new Error(`Failed to load script: ${scriptName}`));
        document.head.appendChild(myScript);
      }));
    }

    // 等待所有脚本加载完成
    Promise.all(scriptLoadPromises)
      .then(() => {
        // 所有动态JS已就绪,执行初始化
        DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);
        alert("JS Files Finished Loading");
        
        // 显示Body内容
        document.body.style.display = "block";
      })
      .catch(error => {
        console.error("Error loading scripts:", error);
        // 可选:加载失败时的 fallback 逻辑,比如显示错误提示
        document.body.style.display = "block";
        alert("Some scripts failed to load, please refresh the page.");
      });
  }
});

方案2:用<template>标签存放Body内容,按需插入

这个方法更“干净”——把原本的Body内容放到<template>标签里(浏览器不会渲染template内的内容),等脚本加载完成后再把内容克隆到Body中。

步骤:

  1. 调整HTML结构,把Body内容移到template里:
<head>
  <!-- 你的head内容和AJAX脚本 -->
</head>
<body class="dx-viewport">
  <!-- 初始Body为空,内容存放在template里 -->
  <template id="body-content-template">
    <!-- 这里放你原本的Body内容,比如: -->
    <h1>My App Content</h1>
    <div class="dx-widget">...</div>
  </template>
</body>
  1. 修改AJAX的成功回调,在脚本加载完成后插入template内容:
// ... 前面的AJAX和Promise部分和方案1一样 ...
Promise.all(scriptLoadPromises)
  .then(() => {
    // 执行初始化逻辑
    DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);
    alert("JS Files Finished Loading");
    
    // 把template内容克隆到Body中
    const template = document.getElementById('body-content-template');
    const content = template.content.cloneNode(true);
    document.body.appendChild(content);
    
    // 可选:移除template标签
    template.remove();
  })
  .catch(error => {
    // 错误处理逻辑
  });

为什么原来的load事件不行?

因为window.load事件会等待所有资源(包括图片、样式表、字体等)加载完成,而你的动态JS加载是在AJAX成功后才开始的,这时候浏览器可能已经开始解析甚至渲染Body内容了,所以时序上赶不上。用Promise.all跟踪每个动态脚本的onload事件,能精准控制在所有依赖JS就绪后再处理Body渲染,时序更可靠。

内容的提问来源于stack exchange,提问作者Paul Pascher

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 07:57:50