在jquery.ajax()加载的页面中运行的脚本过早地运行document.ready

Leo*_*opd 6 jquery jquery-load

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

$(frame_selector).load(url +" #content", function(response, status, xhr) {...});
Run Code Online (Sandbox Code Playgroud)

但是现在我需要能够运行作为动态加载页面一部分的脚本. Jquery.load()剥离这些脚本,但jquery.ajax()没有.所以我复制了jquery.loadajax调用中的部分内容功能:

$.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")
      );
  }
});
Run Code Online (Sandbox Code Playgroud)

问题是从ajax调用动态加载的脚本无法可靠地运行.有时它们似乎没有任何影响,可能是因为它们运行得太早.脚本只是在jquery中进行DOM操作 - 不依赖于图像或flash或任何不应该加载的东西.为了避免陷入困境,我有这个可怕的黑客来让事情发挥作用.而不是仅使用AJAX加载的脚本:

$(document).ready( function() {...} );  // unreliable
Run Code Online (Sandbox Code Playgroud)

我在运行之前将脚本延迟200ms:

$(document).ready( window.setTimeout( function() {...}, 200 )); // HATE THIS
Run Code Online (Sandbox Code Playgroud)

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

Dan*_*ert 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);
Run Code Online (Sandbox Code Playgroud)