【问题标题】:'onload' handler for 'script' tag in internet explorerInternet Explorer 中“脚本”标签的“onload”处理程序
【发布时间】:2011-01-30 21:50:51
【问题描述】:

我一直在使用this function 将 onload 处理程序附加到脚本标签,这似乎是互联网上推荐的方式。
但是,如果页面已经加载(在 ie 8 中测试),它在 Internet Explorer 中不起作用。您可以看到它在普通浏览器中工作(加载脚本时触发警报)。

我错过了什么吗?
谢谢

【问题讨论】:

  • onload 在 IE8 及以下版本中不受支持。它在 IE9 标准模式下工作。
  • @EricLaw 我不确定你的意思,window.attachEvent('onload', fn);到目前为止对我有用(IE 8)。 MSDN 上也提到过
  • @NikitaRybak 我也在尝试实现一种在脚本中加载 jquery 的方法(如果尚未加载),然后在加载时调用函数。不幸的是,ie 中的脚本没有onload。你找到办法了吗?
  • 在使用 async=false 加载脚本时,您可能会发现这很有帮助。 stackoverflow.com/a/13031185/325852

标签: javascript internet-explorer onload


【解决方案1】:

您应该致电jQuery.getScript,这正是您想要的。

编辑:这是来自 jQuery 的相关源代码:

var head = document.getElementsByTagName("head")[0] || document.documentElement;
var script = document.createElement("script");
if ( s.scriptCharset ) {
    script.charset = s.scriptCharset;
}
script.src = s.url;

// Handle Script loading
    var done = false;

// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
    if ( !done && (!this.readyState ||
            this.readyState === "loaded" || this.readyState === "complete") ) {
        done = true;
        jQuery.handleSuccess( s, xhr, status, data );
        jQuery.handleComplete( s, xhr, status, data );

        // Handle memory leak in IE
        script.onload = script.onreadystatechange = null;
        if ( head && script.parentNode ) {
            head.removeChild( script );
        }
    }
};

// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild );

【讨论】:

  • 不会真正起作用,因为 jquery 最初不可用:我必须像这样加载它。但我会检查来源,看看它是否适用于 IE。 +1 提供有趣的参考,谢谢!
  • 一个很好的答案,谢谢伙计,您不必使用 jQuery 来学习这种完全有效的方法,然后编写类似的东西。 :)
  • 我认为“jQuery.handleSuccess(s, xhr, status, data); jQuery.handleComplete(s, xhr, status, data);”可能不是必需的,如果这样做会导致错误逐字使用
  • 请注意,IE9+ 同时支持 script.onload 和 script.onreadystatechange (bit.ly/18gsqtw),因此这两个事件都会被触发(即 2 次调用),这就是为什么需要“完成” .如果您需要将其包装在一个模块中以帮助加载多个脚本,请记住这一点。
  • 你可以找到同样的代码here 准备使用(没有jQuery部分)
【解决方案2】:

我也遇到了 script.onload = runFunction; 的问题。在 IE8 中。

我尝试了 jQuery.getScript,它完美地满足了我的需求。唯一的缺点是在添加脚本之前必须等待加载 jQuery。

但是,由于我的回调函数无论如何都非常大量地使用 jQuery,我发现这是一个非常可接受且非常小的缺点,因为它创建了一个非常易于使用的跨浏览器解决方案。

更新:

这是一种不使用 jQuery 的方法:

(修改后的解决方案来自:https://stackoverflow.com/a/13031185/1339954

var url = 'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js';
var headID = document.getElementsByTagName("head")[0];
var script = document.createElement('script');
script.type='text/javascript';
script.src=url;

//for nonIE browsers
script.onload=function(){
        addVideo();
    }

 //for IE Browsers
 ieLoadBugFix(script, function(){
     addVideo();}
 );

function ieLoadBugFix(scriptElement, callback){
        if (scriptElement.readyState=='loaded' || scriptElement.readyState=='completed') {
             callback();
         }else {
             setTimeout(function() {ieLoadBugFix(scriptElement, callback); }, 100);
         }


 }

headID.appendChild(script);

【讨论】:

  • 看起来 jQuery 设法在没有轮询的情况下解决了这个问题。尝试 onreadystatechange 而不是设置超时
  • ieLoadBugFix 函数做得非常好。它已经测试过了。我很高兴 stackoverflow 如何帮助解决 8 年前提出的解决方案。太棒了
猜你喜欢
  • 2011-03-15
  • 2011-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 2010-10-29
  • 1970-01-01
  • 2015-06-13
相关资源
最近更新 更多