jQuery AJAX 加载的内容是否获得“document.ready”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20246299/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Does AJAX loaded content get a "document.ready"?
提问by
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')
我分配的事件处理程序无法正常工作。原来这是因为我试图.on('click')
在该元素存在于 DOM 之前应用它,因为它是通过 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?
我用一个尴尬的解决方法解决了这个问题,但我的问题是,如果我<script>
在 ajax 加载的内容中放置一个标签,然后在其中放置另一个标签document.ready()
,那么document.ready()
只有在加载完 ajax 内容后才会解析第二个标签吗?换句话说,它是否认为单独加载的 ajax 内容是 another document
,如果是这样,document.ready()
在 ajax 加载的 HTML 中是否有另一个内容像我认为的那样工作?
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()
)
或者; 处理这种情况的更好方法是什么?(需要将事件侦听器附加到尚不存在的 DOM 元素document.ready()
)
采纳答案by nbar
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 内容加载到其中的元素。例如:
$( "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.
因为#id-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
就会触发此点击事件。
回答by Martijn
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 canbind 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();
});
回答by Rudresha Parameshappa
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.
试试这个,这是行不通的,因为您的控件尚未创建,并且您正在尝试附加一个事件,如果您使用 on 事件,它将正常工作。如果您遇到任何问题,请告诉我。
$(document).ready(function(){
$(document).on('click', '#element', function (evt) {
alert($(this).val());
});
});
回答by MonkeyZeus
The answer here is a delegated event:
这里的答案是委托事件:
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>
回答by jeteon
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 v34 中,在动态加载的 HTML 中$(document).ready
的<script>
标签内进行第二次调用似乎等待动态加载的 DOM 加载,然后按照您的描述运行该函数。我不确定这种行为是否是标准行为,因为在尝试使用此类代码进行自动化测试时,它让我感到非常难过。
回答by RoboticRenaissance
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( "加载完成。" ); });