脚本加载后调用javascript函数


81

我有一个html页面,我在其中通过如下所示的javascript动态附加html

<script type="text/javascript" src="/myapp/htmlCode"></script>

我想调用一个js函数,例如,loadedContent(); 一旦以上脚本添加了动态html。

有人可以帮我怎么做吗?

Answers:


140

您可以在不使用head.js javascript的情况下实现这一目标。

function loadScript( url, callback ) {
  var script = document.createElement( "script" )
  script.type = "text/javascript";
  if(script.readyState) {  // only required for IE <9
    script.onreadystatechange = function() {
      if ( script.readyState === "loaded" || script.readyState === "complete" ) {
        script.onreadystatechange = null;
        callback();
      }
    };
  } else {  //Others
    script.onload = function() {
      callback();
    };
  }

  script.src = url;
  document.getElementsByTagName( "head" )[0].appendChild( script );
}


// call the function...
loadScript(pathtoscript, function() {
  alert('script ready!'); 
});

6
仅供参考:onload对于IE 9及更高版本来说onload是可以的-所以现在对于大多数人来说可以进行设置
Simon_Weaver

3
注意onload将在脚本“ LOADS”执行的那一刻开始回调,这令人失望
Ma Dude

@MaDude您可以参考与此相关的任何文档吗?
kontrollanten

2
onload处理器可以当脚本还没有执行完毕,不可能被调用,因为JavaScript是单线程的。这意味着onload只能在脚本开始执行之前或完成执行之后调用处理程序。我个人从未见过前一种情况发生过……永远。如果有人知道onload在脚本开始执行之前可以调用处理程序的可重现情况,请告诉我们。
GetFree

:一个简单的扩展加载脚本的阵列 function loadScripts (urls, callback) {var counter = 0 for (var i=0; i<urls.length; i++) { loadScript(urls[i], function () { if (++counter === urls.length) { callback() } }) } }
SREE

27

我有同样的问题...我的解决方案(没有jQuery):

<script onload="loadedContent();" src ="/myapp/myCode.js"  ></script>

2
请注意:这将与严格的CSP不兼容。
布拉德利,

12

尝试这样的事情

var script = document.createElement('script');

if(script.readyState) {  //IE
script.onreadystatechange = function() {
  if ( script.readyState === "loaded" || script.readyState === "complete" ) {
    script.onreadystatechange = null;
    alert(jQuery);
  }
};
 } else{//others
script.onload = function() {
  alert(jQuery); 
}
}
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.js"
document.documentElement.appendChild(script);

11

如果您在2020年阅读这篇文章,可能您更习惯了Promises。如果您所有的目标浏览器都支持ES6或您正在使用polyfill,则最好使用更现代的方法。

此解决方案的工作方式类似于@JaykeshPatel答案,但它基于Promises:

// definition
function loadScript(scriptUrl) {
  const script = document.createElement('script');
  script.src = scriptUrl;
  document.body.appendChild(script);
  
  return new Promise((res, rej) => {
    script.onload = function() {
      res();
    }
    script.onerror = function () {
      rej();
    }
  });
}

// use
loadScript('http://your-cdn/jquery.js')
  .then(() => {
    console.log('Script loaded!');
  })
  .catch(() => {
    console.error('Script loading failed! Handle this error');
  });

您可以在res回调的参数中传递一些上下文变量,或者,如果您的库导入了一些全局符号,则可以在其中引用它。

例如,由于jQuery引入了$全局符号,因此您可以res($)为其调用并创建局部作用域(如果您使用的是TypeScript,并且不想在每个文件中声明模块变量,则可以这样做const $ = await loadScript(..))。

如果您不想传递任何参数,则可以这样缩短代码:

script.onload = res;
script.onerror = rej;

1
script.onLoad = res;//简化
Kunukn

1
@Kunukn还有一个较短的return new Promise(res => script.onload = res)。但是,将函数分配给起来onload更容易阅读,并允许您传递有关解决的论点
CristianTraìna'19


4

我的答案是Jaykesh Patel答案的扩展。我已经实现了此代码,以便加载多个javascript。希望这对某人有帮助:

// RECURSIVE LOAD SCRIPTS
function load_scripts( urls, final_callback, index=0 )
{
    if( typeof urls[index+1] === "undefined" )
    {
        load_script( urls[index], final_callback );
    }
    else
    {
        load_script( urls[index], function() {
            load_scripts( urls, final_callback, index+1 );
        } );
    }
}

// LOAD SCRIPT
function load_script( url, callback )
{
    var script = document.createElement( "script" );
    script.type = "text/javascript";
    if(script.readyState) // IE
    {
        script.onreadystatechange = function()
        {
            if ( script.readyState === "loaded" || script.readyState === "complete" )
            {
                script.onreadystatechange = null;
                callback();
            }
        };
    }
    else // Others
    {  
        script.onload = function() { callback(); };
    }
    script.src = url;
    document.getElementsByTagName( "head" )[0].appendChild( script );
    debug("javascript included: "+url);
}

// EXAMPLE  
var main = function()
{
    console.log("main function executed");
}
var js = [ "path/to/script-1", "path/to/script-2", "path/to/script-3" ];
load_scripts( js, main );


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.