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

时间:2022-12-06 23:39:49

Yesterday I had an issue where a .on('click') event handler I was assigning wasn't working right. Turns out it's because I was was trying to apply that .on('click') before that element existed in the DOM, because it was being loaded via AJAX, and therefore didn't exist yet when the document.ready() got to that point.

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

I solved it with an awkward workaround, but my question is, if I were to put a <script> tag IN the ajax loaded content and another document.ready() within that, would that second document.ready() be parsed ONLY once that ajax content is done being loaded? In other words, does it consider that separately loaded ajax content to be another document, and if so, does having another document.ready() within that ajax-loaded HTML work the way I think it does?

我用一个尴尬的解决方法解决了它,但我的问题是,如果我将

Alternatively; what would be a better way to handle this situation? (needing to attach an event listener to a DOM element that doesn't yet exist on document.ready())

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

6 个解决方案

#1


31  

To answer your question: No, document.ready will not fire again once a ajax request is completed. (The content in the ajax is loaded into your document, so there isn't a second document for the ajax content).

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

To solve your problem just add the event listener to the Element where you load the ajax content into it. For example:

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

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

For #id-of-the-element-in-the-ajax-content you can use any selector you would use in $("selector"). The only difference is, only elements under div.ajaxcontent-container will be selected.

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

How it works: As long as div.ajaxcontent-container exists all elements (if they exist now or only in the future) that match the selector #id-of-the-element-in-the-ajax-content will trigger this click-event.

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

#2


10  

Javascript in the resulting ajax call will not be excecuted (by default) due to safety. Also, you can't directly bind event to non-existing elements.
You can bind an event to some parent that does exist, and tell it to check it's children:

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

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

Always try to get as close to the triggering element as you can, this will prevent unnessesary bubbling through the DOM

总是试着尽可能接近触发元素,这样可以防止在DOM中冒泡


If you have some weird functions going on, you could do something like this:

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

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();
});

#3


5  

try this, that is not working because your control is not yet created and you are trying to attach a event, if you use on event it will work fine. let me know if you face any issues.

尝试这个,这是行不通的,因为你的控件还没有创建,你试图附加一个事件,如果你使用事件它会工作正常。如果您遇到任何问题,请告诉我。

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

#4


2  

The answer here is a delegated event:

这里的答案是委托事件:

JSFiddle

的jsfiddle

JSFiddle - Truly dynamic

JSFiddle - 真正的动态

jQuery

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

HTML

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

#5


0  

I'm working on a code-base with a friend that has a similar requirement. The delegated event handler option is definitely best if all you want is to attach event handlers. An alternative, especially if you need to do other DOM processing in your $(document).ready function, is to put the code you want run into a script element at the end of your code. Basically, instead of:

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

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

Try swapping the script and the rest of the HTML around so you have:

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

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

This forces the browser to only process your code once it has loaded every other DOM element in the dynamically loaded HTML. Of course this means you'll have to make sure the inserted HTML does not have unintended UI consequences by using CSS/HTML instead of JS. Its an old Javascript trick from years gone by. As a bonus, you don't need jQuery for this anymore.

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

I should mention that in Chromium v34, putting a second $(document).ready call inside a <script> tag in the dynamically loaded HTML seems to wait for dynamically loaded DOM to load and then runs the function as you described. I'm not sure this behaviour is standard though as it has caused me great grief when trying to automate tests with this kind of code in it.

我应该提一下,在Chromium v​​34中,在动态加载的HTML中的

#6


0  

JQuery AJAX .load() has a built-in feature for handling this. Instead of simply $('div#content').load('such_a_such.url'); you should include a callback function. JQuery .load() provides room for the following:

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.");
    }
 );

However, you do not need to include the data argument.

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

$( "#result" ).load( "ajax/test.html", function() { alert( "Load was performed." ); });

$(“#result”)。load(“ajax / test.html”,function(){alert(“Load was performing。”);});

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

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

#1


31  

To answer your question: No, document.ready will not fire again once a ajax request is completed. (The content in the ajax is loaded into your document, so there isn't a second document for the ajax content).

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

To solve your problem just add the event listener to the Element where you load the ajax content into it. For example:

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

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

For #id-of-the-element-in-the-ajax-content you can use any selector you would use in $("selector"). The only difference is, only elements under div.ajaxcontent-container will be selected.

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

How it works: As long as div.ajaxcontent-container exists all elements (if they exist now or only in the future) that match the selector #id-of-the-element-in-the-ajax-content will trigger this click-event.

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

#2


10  

Javascript in the resulting ajax call will not be excecuted (by default) due to safety. Also, you can't directly bind event to non-existing elements.
You can bind an event to some parent that does exist, and tell it to check it's children:

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

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

Always try to get as close to the triggering element as you can, this will prevent unnessesary bubbling through the DOM

总是试着尽可能接近触发元素,这样可以防止在DOM中冒泡


If you have some weird functions going on, you could do something like this:

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

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();
});

#3


5  

try this, that is not working because your control is not yet created and you are trying to attach a event, if you use on event it will work fine. let me know if you face any issues.

尝试这个,这是行不通的,因为你的控件还没有创建,你试图附加一个事件,如果你使用事件它会工作正常。如果您遇到任何问题,请告诉我。

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

#4


2  

The answer here is a delegated event:

这里的答案是委托事件:

JSFiddle

的jsfiddle

JSFiddle - Truly dynamic

JSFiddle - 真正的动态

jQuery

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

HTML

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

#5


0  

I'm working on a code-base with a friend that has a similar requirement. The delegated event handler option is definitely best if all you want is to attach event handlers. An alternative, especially if you need to do other DOM processing in your $(document).ready function, is to put the code you want run into a script element at the end of your code. Basically, instead of:

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

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

Try swapping the script and the rest of the HTML around so you have:

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

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

This forces the browser to only process your code once it has loaded every other DOM element in the dynamically loaded HTML. Of course this means you'll have to make sure the inserted HTML does not have unintended UI consequences by using CSS/HTML instead of JS. Its an old Javascript trick from years gone by. As a bonus, you don't need jQuery for this anymore.

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

I should mention that in Chromium v34, putting a second $(document).ready call inside a <script> tag in the dynamically loaded HTML seems to wait for dynamically loaded DOM to load and then runs the function as you described. I'm not sure this behaviour is standard though as it has caused me great grief when trying to automate tests with this kind of code in it.

我应该提一下,在Chromium v​​34中,在动态加载的HTML中的

#6


0  

JQuery AJAX .load() has a built-in feature for handling this. Instead of simply $('div#content').load('such_a_such.url'); you should include a callback function. JQuery .load() provides room for the following:

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.");
    }
 );

However, you do not need to include the data argument.

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

$( "#result" ).load( "ajax/test.html", function() { alert( "Load was performed." ); });

$(“#result”)。load(“ajax / test.html”,function(){alert(“Load was performing。”);});

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

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