AJAX加载的内容是否会获得“document.ready”?

时间:2013-11-27 15:21:19

标签: jquery event-handling addeventlistener document-ready

昨天我遇到了一个问题,即我分配的.on('click')事件处理程序无法正常工作。事实证明这是因为我试图在DOM中存在该元素之前应用.on('click'),因为它是通过AJAX加载的,因此当document.ready()到达那个点时它还不存在

我用一个尴尬的解决方法解决了这个问题,但我的问题是,如果我要在ajax加载的内容中添加<script>标记而在其中添加另一个document.ready(),那么第二个{{1}只有ajax内容被加载后才被解析?换句话说,它是否认为单独加载的ajax内容是另一个document.ready(),如果是这样,那个加载了ajax的HTML中的另一个document是否像我认为的那样工作?

可替换地;什么是处理这种情况的更好方法? (需要将事件监听器附加到document.ready()上尚不存在的DOM元素)

6 个答案:

答案 0 :(得分:32)

回答你的问题:不,一旦ajax请求完成,document.ready就不会再次触发。 (ajax中的内容已加载到您的文档中,因此ajax内容没有第二个文档。)

要解决您的问题,只需将事件侦听器添加到您将ajax内容加载到其中的Element中。 例如:

$( "div.ajaxcontent-container" ).on( "click", "#id-of-the-element-in-the-ajax-content", function() {
  console.log($( this ));
});

对于#id-of-the-element-in-the-ajax-content,您可以使用在$("selector")中使用的任何选择器。唯一的区别是,只会选择div.ajaxcontent-container下的元素。

工作原理: 只要div.ajaxcontent-container存在与选择器#id-of-the-element-in-the-ajax-content匹配的所有元素(如果它们现在或仅将来存在)将触发此点击事件。

答案 1 :(得分:10)

由于安全原因,在生成的ajax调用中的Javascript不会被禁止(默认情况下)。此外,您不能直接将事件绑定到不存在的元素 你可以将一个事件绑定到一个确实存在的父节点,并告诉它检查它的子节点:

$(document).ready(function(){
    $(document).on('eventName', '#nonExistingElement', function(){ alert(1); }
    // or:
    $('#existingParent').on('eventName', '#nonExistingElement', function(){ alert(1); }
});

总是尝试尽可能接近触发元素,这样可以防止通过DOM进行无关紧要的冒泡


如果你有一些奇怪的功能,你可以这样做:

function bindAllDocReadyThings(){
    $('#nonExistingElement').off().on('eventName', function(){ alert(1); }
    // Note the .off() this time, it removes all other events to set them again
}
$(document).ready(function(){
    bindAllDocReadyThings();
});
$.ajaxComplete(function(){
    bindAllDocReadyThings();
});

答案 2 :(得分:5)

试试这个,因为你的控件尚未创建并且你正在尝试附加一个事件而无法正常工作,如果你使用on事件它将正常工作。如果您遇到任何问题,请告诉我。

$(document).ready(function(){
    $(document).on('click', '#element', function (evt) {
        alert($(this).val());
    });
});

答案 3 :(得分:2)

这里的答案是委托活动:

JSFiddle

JSFiddle - Truly dynamic

<强>的jQuery

$(document).ready(function(){
    // Listen for a button within .container to get clicked because .container is not dynamic
    $('.container').on('click', 'input[type="button"]', function(){
        alert($(this).val());
    });

    // we bound the click listener to .container child elements so any buttons inside of it get noticed
    $('.container').append('<input type="button" class="dynamically_added" value="button2">');
    $('.container').append('<input type="button" class="dynamically_added" value="button3">');
    $('.container').append('<input type="button" class="dynamically_added" value="button4">');
    $('.container').append('<input type="button" class="dynamically_added" value="button5">');
});

<强> HTML

<div class="container">
    <input type="button" class="dynamically_added" value="button1">
</div>

答案 4 :(得分:0)

我正在与一位有类似要求的朋友一起开发代码库。如果你想要的只是附加事件处理程序,那么委托事件处理程序选项绝对是最好的。另一种选择,特别是如果您需要在$(document).ready函数中执行其他DOM处理,则将要运行的代码放入代码末尾的脚本元素中。基本上,而不是:

<script type="text/javascript">
  $(document).ready(function() {
    // Your code here
  });
</script>
<!-- rest of dynamically loaded HTML -->

尝试交换脚本和其他HTML,以便您拥有:

<!-- rest of dynamically loaded HTML -->
<script type="text/javascript">
  // Your code here
</script>

这会强制浏览器只在加载动态加载的HTML中的每个其他DOM元素后才处理代码。当然,这意味着您必须通过使用CSS / HTML而不是JS来确保插入的HTML没有意外的UI后果。它是一个古老的Javascript技巧,从过去几年。作为奖励,你不再需要jQuery了。

我应该提一下,在Chromium v​​34中,在动态加载的HTML中的$(document).ready标记内放置第二个<script>调用似乎等待动态加载的DOM加载,然后运行您所描述的函数。我不确定这种行为是否标准,因为当我尝试使用这种代码自动化测试时,这让我非常悲痛。

答案 5 :(得分:0)

JQuery AJAX .load()具有处理此功能的内置功能。 您应该包含一个回调函数,而不仅仅是$('div#content').load('such_a_such.url');。 JQuery .load()为以下内容提供了空间:

$('div#content').load('such_a_such.url',
    { data1: "First Data Parameter",
      data2: 2,
      data3: "etc" },
    function(){ $('#span1').text("This function is the equivalent of");
                $('#span2').text("the $(document).ready function.");
    }
 );

但是,您不需要包含数据参数。

  

$(“#result”)。load(“ajax / test.html”,function(){      警报(“已执行加载。”);      });

http://api.jquery.com/load/