【问题标题】:iframe behaviour of onload vs addEventListener('load')onload 与 addEventListener('load') 的 iframe 行为
【发布时间】:2011-07-10 09:38:12
【问题描述】:

我一直在尝试向页面添加隐藏的 iframe 元素,并且我想在加载后操纵这些元素的 DOM。我注意到在将 iframe 添加到页面后,我无法立即开始操作 DOM,因为它尚未加载。这不能通过 DOMContentLoaded 事件来完成,因为它会触发 iframe 中不存在的文档,直到它被添加到页面中,所以我们必须使用 load 事件。

这是一些测试代码:

var iframe = document.createElement('iframe');
iframe.onload = function() { console.log('loaded!'); };
document.getElementsByTagName('body')[0].appendChild(iframe);

这按预期工作,但是当我将其更改为 addEventListener 时,它甚至不会被添加到 DOM:

var iframe = document.createElement('iframe');
iframe.addEventListener('load', function() { console.log('loaded!'); });
document.getElementsByTagName('body')[0].appendChild(iframe);

我没有在 IE 中测试过attachEvent

有人对此有所了解吗?

【问题讨论】:

    标签: javascript html iframe onload-event


    【解决方案1】:

    addEventListener() 函数需要 3 个参数!看看https://developer.mozilla.org/en/DOM/element.addEventListener

    第三个参数被标记为可选,但随后他们写道:

    注意这个参数不是 在所有浏览器版本中都是可选的。

    我不确定何时何地需要它,但我在 FF4 上的测试在使用 2 个参数调用 addEventListener 时引发了异常:

    未捕获的异常:[异常...“不是 足够的论据”nsresult: "0x80570001 (NS_ERROR_XPC_NOT_ENOUGH_ARGS)" 位置:“JS框架:: http://localhost/index.php:: ::第10行“数据:无]

    顺便说一句,您的代码在 Chrome 中运行良好[字符串loaded! 已登录到控制台]。

    和 FF 一样,IE9 在标准模式下需要第三个参数(使用<!DOCTYPE html>)。 IE9 是第一个支持 W3C 事件模型的 IE。所以在早期版本中我们需要尝试attachEvent。我没有早期的 IE,但它在 IE7/8 标准模式下工作,甚至在 IE9 的 Quirks 模式下工作。这是我使用的代码:

    <!DOCTYPE html>
    <html>
    <head><title></title></head>
    <body>
    <script>
        window.onload=function(){
            var iframe = document.createElement('iframe');
            var func = function() { console.log('loaded!');};
            if(iframe.addEventListener)
                iframe.addEventListener('load', func, true);
            else if(iframe.attachEvent)
                iframe.attachEvent('onload',func);
            document.body.appendChild(iframe);
        }
    </script>
    </body>
    </html>
    

    【讨论】:

    • 我相信你关于第三个参数的观点正是问题所在,我没有得到你所做的错误,但它可能只是以某种方式被压制了。我不记得了,但很明显我没有在 Chrome 中测试它(我很傻......)。不错,谢谢。
    【解决方案2】:

    这对我有用:

    html:

    iframe source code: <br />
    <textarea id="output" rows="20" cols="60">loading ...</textarea>
    

    javascript(在 documentReady 上):

    var iframe = document.createElement('iframe');
    iframe.id = iframe.name = "testframe";
    iframe.src = "http://fiddle.jshell.net";
    iframe.width = 400;
    iframe.height = 100;
    iframe.style.display = "none";
    
    if (iframe.addEventListener)
        iframe.addEventListener("load", loaded, false);
    else
        iframe.attachEvent("onload", loaded);
    
    function loaded() {
        var html;
        if (iframe.contentDocument)
            html = iframe.contentDocument.getElementsByTagName("HTML")[0].innerHTML;
        else
            html = window.frames[iframe.name].document.getElementsByTagName("html")[0].innerHTML;
    
        document.getElementById("output").value = html;
    }
    
    document.getElementsByTagName("body")[0].appendChild(iframe);
    

    查看演示:http://jsfiddle.net/WcKEz/

    与 addEventListener 一起使用,但包含对 attachEvent 的回退。访问 IFRAME 的 DOM 当然只能在同一个域上。

    【讨论】:

      【解决方案3】:

      第一个例子有效吗?不确定您到底在寻找什么,但这应该会在事件起作用时阐明:jQuery document.ready source

      $(document).ready equivalent without jQuery

      addEventListener 在 IE 中不起作用,因此如果您正在测试那里,那么在附加 iframe 之前第二个将失败。

      您也可以从页面本身添加回调(例如,使用 jQuery,这样您就不会重新发明轮子)我怀疑 $(iframe).ready() {..} 会给您带来一致的行为。

      【讨论】:

      • 不能使用 ready 事件,因为这需要一个尚不存在的文档,除非我遗漏了什么。
      • 我建议在 iframe 元素上使用与 jquery document.ready 相同的逻辑,例如就像这个插件似乎做的那样:thunderguy.com/semicolon/2007/08/14/elementready-jquery-plugin 但仍然不清楚您的第一个代码 sn-p 是否有问题,您是否尝试在加载图像之前进行挂钩?或者,假设您控制 iframe 中的代码,您可以在那里使用 document.ready 回调到使用 parent 的函数。
      • 第一个代码 sn-p 工作正常(如前所述),但是 onload 属性是非标准的(AFAIK),我只是想知道为什么符合标准的方式(忽略 IE)是不工作。 iframe 本身不指向另一个页面,我想将其加载为空白并填充 DOM。
      • onload 似乎没问题:w3schools.com/jsref/event_frame_onload.asp 我有点想念你正在动态构建整个事情。看看这个......老但也许会有所帮助。 bytes.com/topic/javascript/answers/…
      • 哈哈!很公平......虽然我认为他的技术看起来很合理(作为测试访问文档的不同方式的一种方式)。这是一篇更详细的博客文章,内容与似乎初中毕业的人所写的内容相同:thomas.bindzus.me/2007/12/24/adding-dynamic-contents-to-iframes ... 似乎没有任何真正干净的方法可以做到这一点。
      猜你喜欢
      • 1970-01-01
      • 2020-06-06
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2012-09-06
      相关资源
      最近更新 更多