【问题标题】:window.onload not Firing in Embedded html Documentwindow.onload 未在嵌入式 html 文档中触发
【发布时间】:2016-06-23 03:56:23
【问题描述】:

我正在尝试使用 javascript 在另一个中嵌入两个 html 文档。我遇到的问题是 onload 事件不会在嵌入式文档上触发。

paper.htm 有几个 div 标签,应该包含 curve.htm,但在 curve.htm 中,onload 事件没有触发

paper.htm

<html>
<head>
    <title>Curve</title>    
    <script>
        (function () {
            var xhr = new XMLHttpRequest();
            xhr.open('GET', 'curve.htm', true);
            xhr.onreadystatechange = function () {
                if (this.readyState !== 4) return;
                if (this.status !== 200) return;
                document.getElementById('chartBlock').innerHTML = this.responseText;
            }
            xhr.send();
        })();
    </script>
</head>
<body>
    <div id="paper">
        <div id="border">
            <div id="chartBlock"></div>
            <div id="titleBlock"></div>
        </div>
    </div>
</body>
</html>

curve.htm(部分)

<html>
<head>
    <script src="File:///Temp/curveData.js" type="text/javascript"></script>
    <script>
    window.onload = init; //this never fires!
    function init() { //... }
    </script>
<body>
    <canvas id="chartCanvas" width="954" height="625"></canvas>
</body>
</html> 

我试过了:

  1. 使用 jquery 加载 html 文档(SO 上有很多示例)。

  2. 将onload放在html文档(curve.htm)的body标签中

用 jquery 试过:

<script>
    $(function () {
        $("#chartBlock").load("curve.htm");
        $("#titleBlock").load("titleblock.htm");
    });
</script>

用 html 试过:

<body onload="init()">

非常感谢您研究任何其他想法。谢谢

【问题讨论】:

  • div 不是窗口,它不能包含htmlheadbody 标签。更改 div 的 innerHTML 不会在该 div 上触发 onload,无论添加的内容是什么。 onload 仅在自身加载一些外部资源的元素上触发(如 imgiframe)。您可以在设置 div 的innerHTML 后简单地调用init

标签: javascript html dom


【解决方案1】:

因为不会加载文档...

您正在做的事情可以通过 iframe 实现。使用 iframe,您正在加载一个完整的 html 文档,该文档将被解析。使用$.load 函数,你只需直截了当地插入html,它就会被解析为&lt;body&gt; 的孩子。意义; &lt;head&gt;&lt;meta&gt; 标签等将被所有/适当的浏览器忽略,因为它们应该只出现在文档的头部。简化后,您的输出将是:

<html>
    <head>
        <!-- whatever -->
    </head>
    <body>

        <div id="chartBlock">
            <html>
                <!-- What?! Another html tag?! -->
            </html>
        </div>
        <div id="titleBlock">
            <html>
                <!-- And another one... -->
            </html>
        </div>

    </body>
</html>

所以,你想要做的是,只加载内容,即&lt;body&gt; 标签内的内容,并使用$.load 函数的success callback 来做任何你想做的事情如果内容被插入到你的文档中想要做的事情。

【讨论】:

    【解决方案2】:

    您仍然可以在不使用 iframe 的情况下加载页面,您只需要稍微改变一下即可。基本上,由于您将 html 页面放在 div 中,因此该页面上的脚本永远不会被渲染。

    要使其工作,需要将脚本插入到父文档头中。

    获取脚本并插入到head中:

    var head = document.getElementsByTagName('head')[0],
        script = document.createElement('script'),
        data;
    
    script.type = 'text/javascript';
    
    ...
    
    data = document.getElementById('chartBlock')
           .getElementsByTagName('script').item(0).innerHTML;
    
    try {
      script.appendChild(document.createTextNode(data));      
    } catch(e) {
      script.text = data;
    }
    
    head.insertBefore(script, head.firstChild);
    head.removeChild(script);
    

    重新触发加载事件

    var event = new Event('load');
    
    //place after script has been inserted into head
    window.dispatchEvent(event);
    

    使用上面的示例:

    curve.htm

    <html>
       <head>
         <script src="File:///Temp/curveData.js"></script>
         <script>
            window.onload = init; //this will now fire
            function init() { alert('loaded'); }
         </script>
       </head>
       <body>
         <canvas id="chartCanvas" width="954" height="625"></canvas>
       </body>
    </html> 
    

    paper.htm

    <html>
       <head>
         <title>Curve</title>
         <script>
            (function () {
               var xhr = new XMLHttpRequest(),
                   event = new Event('load'),
                   //since the onload event will have already been triggered
                   //by the parent page we need to recreate it.
                   //using a custom event would be best.
                   head = document.getElementsByTagName('head')[0],
                   script = document.createElement('script'),
                   data;
    
               script.type = 'text/javascript';
    
               xhr.open('GET', 'curve.htm', true);
               xhr.onreadystatechange = function (){
                   if (this.readyState !== 4) return;
                   if (this.status !== 200) return;
    
                   document.getElementById('chartBlock').innerHTML = this.responseText;
    
                   data = document.getElementById('chartBlock')
                         .getElementsByTagName('script').item(0).innerHTML;
                   //we're extracting the script containing the
                   //onload handlers from curve.htm,
                   //note that this will only cover the first script section..
    
                   try {
                      // doesn't work on ie
                      script.appendChild(document.createTextNode(data));      
                   } catch(e) {
                      script.text = data;
                   }
    
                   head.insertBefore(script, head.firstChild);
                   head.removeChild(script);
    
                   window.dispatchEvent(event);
                   //once the scripts have been rendered,
                   //we can trigger the onload event
               }
               xhr.send();
            })();
         </script>
       </head>
       <body>
         <div id="paper">
            <div id="border">
               <div id="chartBlock"></div>
               <div id="titleBlock"></div>
            </div>
         </div>
       </body>
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 2012-05-11
      • 2012-12-10
      • 1970-01-01
      • 2010-10-27
      相关资源
      最近更新 更多