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

如何检测动态注入的script脚本是否已完成执行

动态注入script脚本执行完成检测方案

场景1:仅注入同步执行的内联脚本(你当前的实现场景)

你当前的代码中没有给script添加async/defer属性,动态插入的无src属性的内联脚本,会在appendChild调用时同步执行,脚本内所有同步代码执行完成后,才会继续执行appendChild之后的代码。也就是说你现有写法里的someCode()本来就已经是在注入脚本运行完成后才触发的,可以直接正常使用。
验证示例:

const InjectScript = (scriptContent) => {
  const script = document.createElement("script");
  script.type = "text/javascript";
  script.text = scriptContent;
  document.head.appendChild(script);
  // 此处已经可以正常访问注入脚本内定义的变量和方法
  console.log(window.testVal) // 输出123
};
InjectScript(`window.testVal = 123`)

场景2:注入脚本包含异步逻辑,或需要兼容外部src脚本加载

如果注入的脚本里有异步操作(比如接口请求、定时器、async函数),或者后续需要改成加载外部js文件,可以用以下两种方案实现精准监听:

方案1:自定义事件回调(可灵活控制执行时机)

如果可以修改注入的脚本内容,在脚本所有需要执行的逻辑结束后触发自定义事件,外层监听该事件即可:

const InjectScript = (scriptContent, callback) => {
  const eventName = 'customScriptExecuted'
  // 注册一次性事件监听
  window.addEventListener(eventName, () => {
    callback?.()
  }, { once: true })

  const script = document.createElement("script");
  script.type = "text/javascript";
  // 同步逻辑可以直接在脚本末尾拼接事件触发代码,异步逻辑可以在异步回调内主动触发
  script.text = scriptContent;
  document.head.appendChild(script);
};

// 调用示例
InjectScript(`
  setTimeout(() => {
    window.testVal = 123
    // 异步逻辑执行完成后主动触发事件
    window.dispatchEvent(new CustomEvent('customScriptExecuted'))
  }, 1000)
`, () => {
  console.log('脚本逻辑全部执行完成', window.testVal) // 1秒后输出123
})

方案2:通用load事件监听(兼容内联/外部脚本)

如果不需要控制异步逻辑结束时机,只需要监听脚本本身同步代码执行完成,或是加载外部src脚本,可以监听script的load和error事件,用Promise封装更易用:

const InjectScript = (scriptContent, isExternal = false) => {
  return new Promise((resolve, reject) => {
    const script = document.createElement("script");
    script.type = "text/javascript";
    if (isExternal) {
      script.src = scriptContent
    } else {
      script.text = scriptContent
    }
    // 执行/加载成功回调
    script.onload = () => resolve()
    // 执行/加载失败回调
    script.onerror = (err) => reject(err)
    document.head.appendChild(script);
  })
};

// 调用示例:注入内联脚本
InjectScript(`window.testVal = 123`).then(() => {
  console.log('内联脚本同步代码执行完成', window.testVal)
}).catch(err => {
  console.error('脚本执行出错', err)
})

// 调用示例:注入外部脚本
InjectScript('https://example.com/test.js', true).then(() => {
  console.log('外部脚本加载执行完成')
})

注意:内联脚本的load事件在Chrome、Firefox、Safari 10+、Edge等主流浏览器都可以正常触发,仅需要兼容IE9及以下极老旧浏览器时才需要额外做兼容处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:15:02