.append 后的 jQuery 函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6068955/
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
jQuery function after .append
提问by David Horák
How to call a function after jQuery .append
is completely done?
jQuery.append
完成后如何调用函数?
Here's an example:
下面是一个例子:
$("#root").append(child, function(){
// Action after append is completly done
});
The issue: When a complex DOM structure is appended, calculation of new size of the root element within the append function callback is wrong. Assumptions are that the DOM in still not completely loaded, only the first child of the added complex DOM is.
问题:当追加复杂的 DOM 结构时,追加函数回调中根元素的新大小的计算是错误的。假设 DOM 还没有完全加载,只有添加的复杂 DOM 的第一个孩子是。
采纳答案by mekwall
You've got many valid answers in here but none of them really tells you why it works as it does.
你在这里有很多有效的答案,但没有一个能真正告诉你为什么它会这样工作。
In JavaScript commands are executed one at a time, synchronously in the order they come, unless you explicitly tell them to be asynchronous by using a timeout or interval.
在 JavaScript 中,命令一次执行一个,按照它们出现的顺序同步执行,除非您通过使用超时或间隔明确告诉它们是异步的。
This means that your .append
method will be executed and nothing else (disregarding any potential timeouts or intervals that may exist) will execute until that method have finished its job.
这意味着您的.append
方法将被执行,并且在该方法完成其工作之前不会执行任何其他操作(忽略可能存在的任何潜在超时或间隔)。
To summarize, there's no need for a callback since .append
will be run synchronously.
总而言之,不需要回调,因为.append
它将同步运行。
回答by Womi
Well I've got exactly the same problem with size recalculation and after hours of headache I have to disagree with .append()
behaving strictly synchronous. Well at least in Google Chrome. See following code.
好吧,我在大小重新计算方面遇到了完全相同的问题,经过数小时的头痛,我不得不不同意.append()
严格同步的行为。至少在谷歌浏览器中。请参阅以下代码。
var input = $( '<input />' );
input.append( arbitraryElement );
input.css( 'padding-left' );
The padding-left property is correctly retrieved in Firefox but it is empty in Chrome. Like all other CSS properties I suppose. After some experiments I had to settle for wrapping the CSS 'getter' into setTimeout()
with 10 ms delay which I know is UGLY as hell but the only one working in Chrome.
If any of you had an idea how to solve this issue better way I'd be very grateful.
padding-left 属性在 Firefox 中正确检索,但在 Chrome 中为空。就像我想的所有其他 CSS 属性一样。经过一些实验后,我不得不接受将 CSS 'getter' 包装成setTimeout()
10 毫秒的延迟,我知道这很丑陋,但只有一个在 Chrome 中工作。如果你们中有人知道如何更好地解决这个问题,我将不胜感激。
回答by Daniel - SDS Group
Although Marcus Ekwall is absolutely right about the synchronicity of append, I have also found that in odd situations sometimes the DOM isn't completely rendered by the browser when the next line of code runs.
尽管 Marcus Ekwall 关于 append 的同步性是绝对正确的,但我也发现在一些奇怪的情况下,当下一行代码运行时,DOM 并没有完全被浏览器渲染。
In this scenario then shadowdiver solutions is along the correct lines - with using .ready - however it is a lot tidier to chain the call to your original append.
在这种情况下,shadowdiver 解决方案是沿着正确的路线 - 使用 .ready - 但是将调用链接到原始 append 会更整洁。
$('#root')
.append(html)
.ready(function () {
// enter code here
});
回答by jleach
I'm surprised at all the answers here...
我对这里的所有答案感到惊讶......
Try this:
尝试这个:
window.setTimeout(function() { /* your stuff */ }, 0);
Note the 0 timeout. It's not an arbitrary number... as I understand (though my understanding might be a bit shaky), there's two javascript event queues - one for macro events and one for micro events. The "larger" scoped queue holds tasks that update the UI (and DOM), while the micro queue performs quick-task type operations.
请注意 0 超时。这不是一个任意的数字......据我所知(虽然我的理解可能有点不稳定),有两个 javascript 事件队列 - 一个用于宏事件,一个用于微事件。“较大”范围的队列包含更新 UI(和 DOM)的任务,而微队列执行快速任务类型的操作。
Also realize that setting a timeout doesn't guarantee that the code performs exactly at that specified value. What this does is essentially puts the function into the higher queue (the one that handles the UI/DOM), and does not run it before the specified time.
还要意识到设置超时并不能保证代码完全按照指定的值执行。这实际上是将函数放入更高的队列(处理 UI/DOM 的队列),并且不会在指定时间之前运行它。
This means that setting a timeout of 0 puts it into the UI/DOM-portion of javascript's event queue, to be run at the next possible chance.
这意味着将超时设置为 0 会将其放入 javascript 事件队列的 UI/DOM 部分,以在下一个可能的机会运行。
This means that the DOM gets updated with all previous queue items (such as inserted via $.append(...);
, and when your code runs, the DOM is fully available.
这意味着 DOM 会更新所有先前的队列项(例如通过 插入$.append(...);
,并且当您的代码运行时,DOM 完全可用。
(p.s. - I learned this from Secrects of the JavaScript Ninja- an excellent book: https://www.manning.com/books/secrets-of-the-javascript-ninja)
(ps - 我从JavaScript Ninja 的 Secrects中学到了这一点- 一本好书:https: //www.manning.com/books/secrets-of-the-javascript-ninja)
回答by shadowdiver
I came across the same problem and have found a simple solution. Add after calling the append function a document ready.
我遇到了同样的问题,并找到了一个简单的解决方案。在调用 append 函数后添加准备好的文档。
$("#root").append(child);
$(document).ready(function () {
// Action after append is completly done
});
回答by vsync
Using MutationObserver
can act like a callback for the jQuery append
method:
UsingMutationObserver
可以充当 jQueryappend
方法的回调:
I've explained it in another question, and this time I will only give example for modern browsers:
// 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>');
回答by msangel
I have another variant which may be useful for someone:
我有另一个可能对某人有用的变体:
$('<img src="http://example.com/someresource.jpg">').load(function() {
$('#login').submit();
}).appendTo("body");
回答by James Jones
I think this is well answered but this is a bit more specific to handling the "subChild_with_SIZE" (if that's coming from the parent, but you can adapt it from where it may be)
我认为这是一个很好的回答,但这更具体地处理“subChild_with_SIZE”(如果它来自父级,但您可以从它可能的位置进行调整)
$("#root").append(
$('<div />',{
'id': 'child'
})
)
.children()
.last()
.each(function() {
$(this).append(
$('<div />',{
'id': $(this).parent().width()
})
);
});
回答by renatoluna
$.when($('#root').append(child)).then(anotherMethod());
$.when($('#root').append(child)).then(anotherMethod());
回答by Dve
the Jquery append function returns a jQuery object so you can just tag a method on the end
Jquery append 函数返回一个 jQuery 对象,因此您可以在末尾标记一个方法
$("#root").append(child).anotherJqueryMethod();