用远程src注入脚本标签并等待它执行

我怎样才能将一个<script src="https://remote.com/"></script>元素注入到我的页面中,等待它执行,然后使用它定义的函数?

仅供参考:就我而言,脚本将在极less数情况下进行信用卡处理,因此我不希望将其包含在内。 我希望在用户打开更改信用卡选项对话框时快速将其包括在内,然后向其发送新的信用卡选项。

编辑更多的细节:我没有访问远程脚本。

您可以使用Google AnalyticsFacebook的方法:

 (function(d, script) { script = d.createElement('script'); script.type = 'text/javascript'; script.async = true; script.onload = function(){ // remote script has loaded }; script.src = 'ga.js'; d.getElementsByTagName('head')[0].appendChild(script); }(document)); 

更新:

下面是新的Facebook方法; 它依赖于现有的脚本标记而不是<head>

 (function(d, s, id){ var js, fjs = d.getElementsByTagName(s)[0]; if (d.getElementById(id)){ return; } js = d.createElement(s); js.id = id; js.onload = function(){ // remote script has loaded }; js.src = "//connect.facebook.net/en_US/sdk.js"; fjs.parentNode.insertBefore(js, fjs); }(document, 'script', 'facebook-jssdk')); 
  • facebook-jssdkreplacefacebook-jssdk唯一的脚本标识符,以避免多次添加它。
  • 用你自己的replace脚本的URL。

使用事件侦听器和ES2015构造的相同方法:

 function injectScript(src) { return new Promise((resolve, reject) => { const script = document.createElement('script'); script.async = true; script.src = src; script.addEventListener('load', resolve); script.addEventListener('error', () => reject('Error loading script.')); script.addEventListener('abort', () => reject('Script loading aborted.')); document.head.appendChild(script); }); } injectScript('http://example.com/script.js') .then(() => { console.log('Script loaded!'); }).catch(error => { console.log(error); }); 

像这样的事情应该做的伎俩:

 (function() { // Create a new script node var script = document.createElement("script"); script.type = "text/javascript"; script.onload = function() { // Cleanup onload handler script.onload = null; // do stuff with the loaded script! } // Add the script to the DOM (document.getElementsByTagName( "head" )[ 0 ]).appendChild( script ); // Set the `src` to begin transport script.src = "https://remote.com/"; })(); 

希望有所帮助! 干杯。

这是同步dynamic加载和执行脚本列表的一种方法。 您需要将每个脚本标记插入到DOM中,明确将其async属性设置为false:

 script.async = false; 

已经注入DOM的脚本默认是asynchronous执行的,所以你必须手动设置async属性为false来解决这个问题。

 <script> (function() { var scriptNames = [ "jquery.min.js", "example.js" ]; for (var i = 0; i < scriptNames.length; i++) { var script = document.createElement('script'); script.src = scriptNames[i]; script.async = false; // This is required for synchronous execution document.head.appendChild(script); } // jquery.min.js and example.js will be run in order and synchronously })(); </script> <!-- Gotcha: these two script tags may still be run before `jquery.min.js` and `example.js` --> <script src="example2.js"></script> <script>/* ... */<script> 

参考

  • Google的杰克·阿奇博尔德(Jake Archibald)有一篇很棒的文章,叫做深入潜入脚本加载的黑暗水域 。
  • 标签上的WHATWG规范是如何加载标签的一个很好和彻底的描述。