6

我的网站jquery.load()用于在页面的一大块上进行导航。我真的很欣赏只包含加载内容的特定部分的能力,这里是 id="content" 的 div:

$(frame_selector).load(url +" #content", function(response, status, xhr) {...});

但现在我需要能够运行作为动态加载页面一部分的脚本。 Jquery.load()去掉这些脚本,但jquery.ajax()没有。jquery.load因此,我复制了 ajax 调用中的部分内容功能,如下所示:

$.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 操作——不依赖于图像或闪存或任何不应该加载的东西。为了不被卡住,我有这个可怕的黑客来让事情正常进行。而不是仅使用 AJAX 加载的脚本:

$(document).ready( function() {...} );  // unreliable

我在运行前将脚本延迟 200 毫秒:

$(document).ready( window.setTimeout( function() {...}, 200 )); // HATE THIS

有谁知道我如何在不延迟硬编码的情况下使这项工作可靠地工作?我猜这是<script>加载#content到新 div 和我的逻辑之间的竞争条件,但我不知道该怎么做。

4

2 回答 2

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);
于 2010-11-02T00:00:48.573 回答
1

@Dan 有答案。通过 ajax 加载脚本时,文档isReady为 true。这意味着如果这是您的 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 函数加载脚本,它将创建一个闭包。此关闭将持续页面的生命周期。每次您请求该脚本而不刷新页面时都会创建内存泄漏

于 2010-11-02T04:19:01.450 回答