我的网站正在使用jquery.load()
在网页的大部分区域进行导航。我真的很感激能够只包含加载内容的特定部分,这里是id =“content”的div:
$(frame_selector).load(url +" #content", function(response, status, xhr) {...});
但是现在我需要能够运行作为动态加载页面一部分的脚本。 Jquery.load()
删除了这些脚本,但jquery.ajax()
没有。所以我在ajax调用中复制了jquery.load
的部分内容功能:
$.ajax({
url: url,
dataType: 'html',
success: function(data, textStatus, XMLHttpRequest) {
// Only include the response within the #content id element.
$(frame_selector).html( jQuery("<div>")
.append(data)
.find("#content")
);
}
});
问题是从ajax调用动态加载的脚本无法可靠地运行。有时它们似乎没有任何影响,可能是因为它们运行得太早。脚本只是在jquery中进行DOM操作 - 不依赖于图像或flash或任何不应该加载的东西。为了避免陷入困境,我有这个可怕的黑客来让事情发挥作用。而不是仅使用AJAX加载的脚本:
$(document).ready( function() {...} ); // unreliable
我在运行之前将脚本延迟200ms:
$(document).ready( window.setTimeout( function() {...}, 200 )); // HATE THIS
任何人都知道如何在没有硬编码延迟的情况下可靠地完成这项工作?我猜这是<script>
和我的逻辑之间的竞争条件,将#content
加载到一个新div中,但我不知道该怎么办。
答案 0 :(得分:7)
我假设脚本正在对你通过AJAX添加的DOM元素进行操作。
jQuery具有isReady
属性,一旦在页面上触发了ready
事件,它就会设置该属性。
对jQuery.ready(...)
的任何后续调用都将首先检查此isReady
标记。如果该标志设置为true,它将立即调用该处理程序。您可以看到为什么这会导致代码出现问题。
一种选择是将响应加载到jQuery片段中并解析出所有<script />
标记以便稍后执行。
var ajaxResponse = $(html);
var scripts = ajaxResponse.find('script');
// Move your scripts into a new element
var tempScripts = $().append(scripts);
// Append your content, followed by your script tags
$(document).append(ajaxResponse);
$(document).append(tempScripts);
答案 1 :(得分:1)
@Dan有答案。通过ajax加载脚本时,文档isReady
为真。这意味着如果这是您的ajax请求所请求的脚本标记:
<script type="text/javascript">
if (jQuery.isReady) {
$('body').append("<div id='new_content'>Document Ready</div>");
}
else {
$('body').append("<div id='new_content'>Document Not Ready</div>");
}
</script>
而不是解析利用JSON。一个属性将包含HTML。另一个属性将保存脚本。
然后你可以这样做:
$(document).append(ajaxResponse.html);
$(document).append(ajaxResponse.script);
此外,如果您使用围绕代码的ready函数加载脚本,它将创建一个闭包。此闭包将持续页面的生命周期。每次请求脚本而不刷新页面时都会创建内存泄漏