jQuery .append完成后如何调用函数?
这是一个例子:
$("#root").append(child, function(){
// Action after append is completly done
});
问题:当添加复杂的DOM结构时,在append函数回调中计算根元素的新大小是错误的。假设DOM仍未完全加载,只有添加的复杂DOM的第一个子代才加载。
jQuery .append完成后如何调用函数?
这是一个例子:
$("#root").append(child, function(){
// Action after append is completly done
});
问题:当添加复杂的DOM结构时,在append函数回调中计算根元素的新大小是错误的。假设DOM仍未完全加载,只有添加的复杂DOM的第一个子代才加载。
Answers:
您在这里有很多有效的答案,但是没有一个能真正告诉您它为什么如此有效。
在JavaScript中,除非您通过使用超时或间隔明确告诉它们是异步的,否则命令一次才能执行,并且顺序是同步的。
这意味着您 .append方法将被执行,并且在该方法完成其工作之前,将不执行任何其他操作(不考虑任何潜在的超时或间隔)。
总而言之,由于.append将同步运行,因此无需回调。
好吧,我在重新计算尺寸时遇到了完全相同的问题,经过数小时的头痛之后,我不同意.append()严格同步的行为。至少在Google Chrome中是如此。请参阅以下代码。
var input = $( '<input />' );
input.append( arbitraryElement );
input.css( 'padding-left' );
在Firefox中可以正确检索padding-left属性,但在Chrome中为空。像我想的所有其他CSS属性一样。经过一些实验后,我不得不适应将CSS'getter'封装为setTimeout()10毫秒的延迟,我知道这很丑陋,但唯一在Chrome中工作的。如果您有任何想法如何更好地解决此问题,我将不胜感激。
.ready()更好,更优雅的解决方案的答案。
尽管Marcus Ekwall关于append的同步性是绝对正确的,但我还发现,在奇怪的情况下,有时当下一行代码运行时,浏览器无法完全呈现DOM。
在这种情况下,shadowdiver解决方案将遵循正确的思路-使用.ready-不过,将调用链接到您的原始追加文件要好得多。
$('#root')
.append(html)
.ready(function () {
// enter code here
});
我对这里的所有答案感到惊讶...
试试这个:
window.setTimeout(function() { /* your stuff */ }, 0);
注意0超时。这不是一个任意的数字...据我了解(尽管我的理解可能有些不稳定),有两个javascript事件队列-一个用于宏事件,一个用于微事件。“较大”范围的队列包含更新UI(和DOM)的任务,而微队列执行快速任务类型的操作。
还应意识到,设置超时并不能保证代码完全按照该指定值执行。这实际上是将函数放入较高的队列(处理UI / DOM的队列),并且不在指定时间之前运行它。
这意味着将超时设置为0会将其放入javascript事件队列的UI / DOM部分,以便在下一次可能的机会上运行。
这意味着DOM将使用所有先前的队列项目(例如通过插入)进行更新$.append(...);,并且在您的代码运行时DOM完全可用。
(ps-我从JavaScript忍者的秘诀中学到了这本书-很棒的书:https : //www.manning.com/books/secrets-of-the-javascript-ninja)
setTimeout()多年了,不知道为什么。感谢您的解释!
我还有另一种可能对某人有用的变体:
$('<img src="http://example.com/someresource.jpg">').load(function() {
$('#login').submit();
}).appendTo("body");
...on('load', function(){ ... 在这里使用它:stackoverflow.com/a/37751413/2008111
我遇到了同样的问题,并找到了一个简单的解决方案。调用append函数后添加一个文档准备就绪。
$("#root").append(child);
$(document).ready(function () {
// Action after append is completly done
});
使用MutationObserver可以像jQuery的回调一样append方法:
我已经在另一个问题中对此进行了解释,这一次,我仅给出现代浏览器的示例:
// Somewhere in your app:
var observeDOM = (() => {
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
return function(obj, callback){
if( MutationObserver ){
// define a new observer
var obs = new MutationObserver(function(mutations, observer){
if( mutations[0].addedNodes.length || mutations[0].removedNodes.length )
callback(mutations);
});
// have the observer observe foo for changes in children
obs.observe( obj, { childList:true, subtree:true });
return obs;
}
}
})();
//////////////////
// Your code:
// setup the DOM observer (on the appended content's parent) before appending anything
observeDOM( document.body, ()=>{
// something was added/removed
}).disconnect(); // don't listen to any more changes
// append something
$('body').append('<p>foo</p>');
$.when($('#root').append(child)).then(anotherMethod());
$.when仅适用于那些返回承诺对象的对象
anotherMethod()。.不会作为回调传递。
Jquery append函数返回一个jQuery对象,因此您只需在最后标记一个方法
$("#root").append(child).anotherJqueryMethod();
在为移动设备编码HTML5时遇到了此问题。某些浏览器/设备组合会导致错误,因为.append()方法没有立即反映出DOM中的更改(导致JS失败)。
通过这种情况的快速解决方案是:
var appint = setInterval(function(){
if ( $('#foobar').length > 0 ) {
//now you can be sure append is ready
//$('#foobar').remove(); if elem is just for checking
//clearInterval(appint)
}
}, 100);
$(body).append('<div>...</div><div id="foobar"></div>');
是的,您可以在任何DOM插入中添加回调函数:
$myDiv.append( function(index_myDiv, HTML_myDiv){
//....
return child
})
检查JQuery文档:http : //api.jquery.com/append/
这是一个实用的类似示例:http :
//www.w3schools.com/jquery/ tryit.asp?filename = tryjquery_html_prepend_func
.prepend()方法替换为:$(“ p”)。prepend(function(n,pHTML){return“ <b>此p元素</ b>(\” <i >“ + pHTML +” </ i> \“)<b>的索引为” + n +“ </ b>。”
我最近遇到了类似的问题。对我来说,解决方案是重新创建该集合。让我尝试证明:
var $element = $(selector);
$element.append(content);
// This Doesn't work, because $element still contains old structure:
$element.fooBar();
// This should work: the collection is re-created with the new content:
$(selector).fooBar();
希望这可以帮助!
我知道这不是最佳解决方案,而是最佳实践:
$("#root").append(child);
setTimeout(function(){
// Action after append
},100);
$('#root').append(child);
// do your work here
Append没有回调,并且这是同步执行的代码-没有未完成的风险
append()花费很少的时间。