2011-08-24 64 views
1

我有一个页面,我正在使用jquery/ajax从另一个组件中拉下一大块HTML/JS并将它注入到页面中。该HTML引用额外的JS文件,并且我需要那些被引用的JS文件在我运行我的JavaScript之前加载。远程JavaScript加载后执行本地Javascript?

正被注入的HTML/JS看起来是这样的:

<script type="text/javascript" src="http://myserver/js/ABunchOfStuff.js"></script> 
<div> 
    blah blah blah 
</div> 
<script type="text/javascript"> 
    //"sourceList" is defined in the ABunchOfStuff.js above, but it's not available by the time this executes. 
    $("input#autocomplete").autocomplete({ 
     source: sourceList, 
     minLength: 2 
    }); 
</script> 

通常我会只是挂钩到一个窗口加载事件或$(文件)。就绪()或什么,但在这如果窗口和文档已经完全加载,现在我们会在事实之后添加更多内容。

有一种可能性是将一个递归setTimeout调用放到引用的javascript可用,但这很丑陋。

那么是否有任何干净的方式来捕获引用的JavaScript事件已被加载,并在当时执行代码?

感谢

+0

你确定吗?你拥有它的方式,直到'ABunchOfStuff.js'被下载并可用,甚至'div'都不会被渲染。 – Mrchief

+0

你有没有尝试把代码放在'$(function(){});'?所以它只在DOM准备好时才执行? http://api.jquery.com/ready/ –

回答

4

您还可以使用getScript,并在成功回调做你autoComplete

jQuery.getScript('http://myserver/js/ABunchOfStuff.js', function(data, textStatus) { 
     $("input#autocomplete").autocomplete({ 
      source: sourceList, 
      minLength: 2 
     }); 
}); 
+0

非常感谢,谢谢! –

0

最大的问题是,如何你注入这个脚本?

如果使用“标准”脚本标记插入,则可以去看看onload事件(IE中的onreadystatechange)。

var scr = document.createElement('script'); 
    scr.type = 'text/javascript'; 
    scr.src = 'somewhere/somename.js'; 
    scr.onload = scr.onreadystatechange = function() { 
     if(/complete|loaded/.test(scr.readyState)) { 
      // do something 
     } 
     else { 
      // do something 
     } 
    }; 
+0

我正在使用JQuery来执行$ .post调用来检索内容,然后.html()方法将HTML和JS放入容器div –

0

你在做什么错在这里没有等待DOM加载。

如果您改变.autocomplete只执行一次的DOM加载通过$(document).ready将已经执行了ABunchOfStuff.js

像这样:如果你控制http://myserver/js/ABunchOfStuff.js文件

(function($) { 
    $(document).ready(function() { 
    $("input#autocomplete").autocomplete({ 
     source: sourceList, 
     minLength: 2 
    }); 
    } 
}(jQuery)); 
+0

在我的情况下,DOM已经加载。在页面加载完成后,这些内容将被很好地添加到页面中,因此document.ready事件早已消失。 –

+0

那么为什么你的外部JavaScript没有执行?一旦dom准备就绪,JavaScript就已经被执行了。 – Tigraine

0

然后,你可以在第一次执行时调用你的其他JS。由于它在首次加载时以及可用时执行,因此您拥有完美的时间。

如果这个JS文件用于其他地方也一样,当它执行加入这样的事情吧,你可以添加一些通用的功能,它调用回调:

try { 
    if (aBunchOfStuffCallbacks) { 
     for (var i = 0; i < aBunchOfStuffCallbacks.length; i++) { 
      aBunchOfStuffCallbacks[i].call(this); // call callback to announce we're loaded 
     } 
    } catch(e) {} 

而且,当时在任何网络您想aBunchOfStuffCallbacks加载时调用页面,你只需做到这一点:

var aBunchOfStuffCallbacks = []; 
aBunchOfStuffCallbacks.push(myFunc); 
function myFunc() { 
    // put my code here for when aBunchOfStuffCallbacks is loaded 
} 

这将允许多个回调。只是一个回调的简单的版本是这样的:

try { 
    if (aBunchOfStuffCallback) { 
      aBunchOfStuffCallback.call(this); // call callback to announce we're loaded 
     } 
    } catch(e) {} 

而且,它是这样设置的:

var aBunchOfStuffCallbacks = function() { 
    // put my code here for when aBunchOfStuffCallbacks is loaded 
} 
+0

我控制它,但它是一个包含文件,其中包含几个不同页面使用的一些常用功能。我不想将任何特定于页面的逻辑刻录到通用包含文件中 –

+0

您可以让它查找全局回调变量并仅在该全局变量存在时调用该回调。然后你会添加更多的通用功能到包含的JS文件中,在需要时可以使用它,并且在不需要时不会执行任何操作。查看我添加到我的答案的细节。 – jfriend00