如何在jQuery .append
完全完成后调用一个函数?
这是一个例子:
$("#root").append(child, function(){
// Action after append is completly done
});
问题:在添加复杂的DOM结构时,在附加函数回调中计算根元素的新大小是错误的。假设DOM仍未完全加载,只有添加的复杂DOM的第一个子级加载完成。如何在jQuery .append
完全完成后调用一个函数?
这是一个例子:
$("#root").append(child, function(){
// Action after append is completly done
});
问题:在添加复杂的DOM结构时,在附加函数回调中计算根元素的新大小是错误的。假设DOM仍未完全加载,只有添加的复杂DOM的第一个子级加载完成。这里有很多有效的答案,但它们没有真正告诉你为什么以这种方式工作。
在JavaScript中,命令按顺序同步执行,除非您通过使用超时或间隔显式地将它们设置为异步执行。
这意味着您的 .append
方法将被执行,除非该方法完成其工作(不考虑任何可能存在的超时或间隔),否则不会执行其他任何操作。
总之,由于.append
将同步运行,因此不需要回调函数。
虽然Marcus Ekwall关于append方法的同步性是完全正确的,但我也发现在一些特殊情况下,当下一行代码运行时,浏览器有时无法完全渲染DOM。
在这种情况下,shadowdiver的解决方案沿用了使用.ready方法的正确思路,但更加简洁的方式是将原始的append方法与其链接起来。
$('#root')
.append(html)
.ready(function () {
// enter code here
});
我也遇到了尺寸重新计算的同样问题,经过几个小时的头疼之后,我不得不反对.append()
在严格意义上的同步行为。至少在Google Chrome浏览器中是这样的。请看下面的代码。
var input = $( '<input />' );
input.append( arbitraryElement );
input.css( 'padding-left' );
在 Firefox 中可以正确地检索到 padding-left 属性,但在 Chrome 中为空。我想其他 CSS 属性也是如此。经过一些实验,我不得不将 CSS "getter" 包装在带有 10 毫秒延迟的 setTimeout()
中,这很丑陋但是在 Chrome 中是唯一可行的方法。
如果您有更好的解决方法,请告诉我,我将不胜感激。
.ready()
的答案更好,更优雅的解决方案。 - Mark Carpenter Jrwindow.setTimeout(function() { /* your stuff */ }, 0);
$.append(...);
插入),当您的代码运行时,DOM完全可用。setTimeout()
,但不知道为什么。感谢您的解释! - steampoweredsetTimeout(fn(), 0)
不会等待几秒钟,它只是给setTimeout()
之前的代码更高的优先级。 - NHerwich$("#root").append(child);
$(document).ready(function () {
// Action after append is completly done
});
我还有另一种变体可能对某些人有用:
$('<img src="http://example.com/someresource.jpg">').load(function() {
$('#login').submit();
}).appendTo("body");
...on('load', function(){ ...
在这里查看:https://dev59.com/vFoU5IYBdhLWcg3wK0pX#37751413 - caramba使用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>');
<script>
标签放在</body>
之前的底部位置。 - vsync我认为已经有很好的回答了,但是这更加具体,涉及到处理“subChild_with_SIZE”(如果这是从父级传递而来的,但你可以从其他地方进行调整)。
$("#root").append(
$('<div />',{
'id': 'child'
})
)
.children()
.last()
.each(function() {
$(this).append(
$('<div />',{
'id': $(this).parent().width()
})
);
});
JQuery的append函数返回一个jQuery对象,因此您可以在结尾处添加一个方法
$("#root").append(child).anotherJqueryMethod();
$.when($('#root').append(child)).then(anotherMethod());
$.when
只适用于返回 Promise 对象的对象。 - RifatanotherMethod()
的情况下才起作用。它不会被传递为回调函数。 - yts
append()
几乎不需要什么时间。 - Bojangles