js加载一个外部script,这个script执行后会当前页面插入dom结构,如何确切获取到dom结构插入完成?

项目是 vue 单页应用

具体来说就是后台会返回给我一个 script 地址,我用 js 创建 script 标签然后插入到 head 中,这个 script 会生成一个 flash 插入到 html 底部,这个时候插入的位置是和 vue 中的 app 同级的,所以 vue 的生命周期 mounted 监控不到。

我怎么做才能完美的知道 dom 已插入完毕,方便我移动这个 dom 的位置,太早执行函数会获取不到dom,太晚用户会看到位置不对。

我目前是用定时器,插入 script 1s 后执行 dom 操作。

有没有更优雅的办法呢?

clipboard.png

clipboard.png

阅读 3k
3 个回答
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Demo</title>
</head>
<body>
  <div id="app">
    <p>{{text}}</p>
  </div>
  <script src="https://cdn.staticfile.org/vue/2.6.10/vue.js"></script>
  <script>
    (function() {
      new Vue({
        el: '#app',
        data: {
          text: 'this is app text',
        }
      })
      const observer = new MutationObserver(mutations => {
        mutations.forEach(({type, addedNodes}) => {
          if(type === 'childList' && addedNodes.length && addedNodes[0].id === 'flash') console.log('flashDOM插入完毕');
        })
      });
      observer.observe(document.body,{ childList: true, attributes: false,subtree: false, });
      
      const script = document.createElement('script');
      script.src = 'index.js';
      // 如果脚本里的DOM是立即插入的话,在onload里就可以获取到了。
      // 反之,如果DOM是延迟插入的话,如在setTimeout(() => document.body.appendChild(flash), 1000);
      // 那么就用MutationObserve去检测
      script.onload = () => console.log(document.querySelector('#flash'))
      document.head.appendChild(script);
    })();
  </script>
</body>
</html>
// index.js
(() => {
  const flash = document.createElement('div');
  flash.id = 'flash';
  flash.innerHTML = '<p>this is flash content</p>';
  document.body.appendChild(flash);
})();
  1. 确定插入DOM节点特征(如id)。
  2. 添加MutationObserver对插入节点的父级节点进行监测。
  3. 当观察到DOM节点变动时,判断目标节点是否已经存在。
  4. 取消监测。并进行后续操作。

注意:被移入Vue渲染出的DOM节点中的文档碎片片段可能会由于Vue的重新渲染丢失!

后来我想了下 可以通过 iframe 来解决,在想插入的位置写个 iframe 然后 script 插入在 iframe 中,位置就固定住了,我也不需要去获知它什么时候加载完毕。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题