我有一个发送 Ajax 命令的系统,该命令返回一个包含函数的脚本块。将此数据正确插入 DIV 后,我希望能够调用此函数来执行所需的操作。
这可能吗?
我有一个发送 Ajax 命令的系统,该命令返回一个包含函数的脚本块。将此数据正确插入 DIV 后,我希望能够调用此函数来执行所需的操作。
这可能吗?
我认为在这种形式下正确解释您的问题:“好吧,我已经完成了所有 Ajax 的工作;我只想知道我的 Ajax 回调插入到 DIV 中的 JavaScript 函数是否可以从那一刻起随时调用,也就是说,我不想在上下文中调用它到回调返回”。
好的,如果您的意思是这样,那么答案是肯定的,您可以在浏览器中的页面持久化期间的任何时刻调用您的新代码,在以下条件下:
1) 你的 Ajax 回调返回的 JavaScript 代码必须在语法上没问题;
2) 即使您的函数声明被插入到<script>
现有<div>
元素中的块中,浏览器也不会知道新函数的存在,因为声明代码从未被执行过。因此,您必须eval()
通过 Ajax 回调返回您的声明代码,以便有效地声明您的新函数并使其在整个页面生命周期内可用。
即使很傻,这段代码也解释了这个想法:
<html>
<body>
<div id="div1">
</div>
<div id="div2">
<input type="button" value="Go!" onclick="go()" />
</div>
<script type="text/javascript">
var newsc = '<script id="sc1" type="text/javascript">function go() { alert("GO!") }<\/script>';
var e = document.getElementById('div1');
e.innerHTML = newsc;
eval(document.getElementById('sc1').innerHTML);
</script>
</body>
</html>
我没有使用 Ajax,但概念是一样的(即使我选择的例子肯定不是很聪明:-)
一般来说,我不质疑您的解决方案设计,即在单独的 .js 文件中外部化 + 泛化该功能是否或多或少合适,但请注意,这样的解决方案可能会引发更多问题,尤其是如果你的 Ajax 调用应该重复,即如果同一个函数的上下文应该改变或者如果声明的函数持久性应该被关注,那么也许你应该认真考虑将你的设计更改为这个线程中建议的示例之一。
最后,如果我误解了你的问题,并且当你的 Ajax 回调返回时你正在谈论函数的上下文调用,那么我的感觉是建议krosenvold 描述的 Prototype 方法,因为它是跨浏览器的,经过测试并且功能齐全,这可以为您提供更好的未来实施路线图。
注意: eval() 很容易被误用,假设请求被第三方拦截并向您发送不可信的代码。然后使用 eval() 您将运行这个不受信任的代码。请参阅此处了解eval()的危险。
在返回的 HTML/Ajax/JavaScript 文件中,您将有一个 JavaScript 标记。给它一个 ID,比如runscript。向这些标签添加 id 并不常见,但需要专门引用它。
<script type="text/javascript" id="runscript">
alert("running from main");
</script>
在主窗口中,然后通过仅评估新的 JavaScript 代码块(在本例中,它称为runscript)来调用 eval 函数:
eval(document.getElementById("runscript").innerHTML);
它可以工作,至少在 Internet Explorer 9 和 Google Chrome 中是这样。
这是完全可能的,甚至有一些相当合法的用例。使用Prototype框架按如下方式完成。
new Ajax.Updater('items', '/items.url', {
parameters: { evalJS: true}
});
请参阅Ajax 更新程序的文档。选项位于公共选项集中。像往常一样,有一些关于“this”指向哪里的警告,所以请阅读细则。
JavaScript 代码将在加载时进行评估。如果内容包含功能,myFunc(),
您真的可以myFunc()
事后说。也许如下。
if (window["myFunc"])
myFunc()
这将检查该函数是否存在。也许有人有更好的跨浏览器方式来完成在 Internet Explorer 6 中的工作。
这对于您的代码来说似乎是一个相当奇怪的设计 - 通常让您的函数直接从 .js 文件中调用更有意义,然后只使用 Ajax 调用检索数据。
但是,我相信它应该通过对响应调用eval()来工作- 只要它是语法正确的 JavaScript 代码。
使用 jQuery 我会使用getScript