Как вызвать функцию после того, как jQuery .append
полностью завершен?
Вот пример:
$("#root").append(child, function(){
// Action after append is completly done
});
Проблема: когда добавляется сложная структура DOM, вычисление нового размера корневого элемента в обратном вызове функции добавления неверно. Предполагается, что DOM еще не полностью загружен, только первый дочерний элемент добавленной сложной DOM.
append()
занимает очень мало времени.Ответы:
У вас есть много правильных ответов, но ни один из них не говорит вам, почему это работает именно так.
В JavaScript команды выполняются по одной за раз, синхронно в порядке их поступления, если вы явно не укажете, что они должны быть асинхронными, используя тайм-аут или интервал.
Это означает, что ваш
.append
метод будет выполнен, и больше ничего (без учета возможных тайм-аутов или интервалов, которые могут существовать) не будет выполняться, пока этот метод не завершит свою работу.Подводя итог, нет необходимости в обратном вызове, поскольку
.append
он будет выполняться синхронно.источник
Хотя Маркус Эквалл абсолютно прав насчет синхронности добавления, я также обнаружил, что в странных ситуациях иногда DOM не полностью отображается браузером при выполнении следующей строки кода.
В этом сценарии решения shadowdiver находятся в правильном направлении - с использованием .ready - однако гораздо проще связать вызов с исходным дополнением.
$('#root') .append(html) .ready(function () { // enter code here });
источник
Что ж, у меня точно такая же проблема с пересчетом размера, и после нескольких часов головной боли я не согласен с тем, чтобы
.append()
вести себя строго синхронно. Хорошо хоть в Google Chrome. См. Следующий код.var input = $( '<input />' ); input.append( arbitraryElement ); input.css( 'padding-left' );
Свойство padding-left правильно извлекается в Firefox, но в Chrome оно пусто. Полагаю, как и все другие свойства CSS. После некоторых экспериментов мне пришлось довольствоваться заключением «геттера» CSS
setTimeout()
с задержкой в 10 мс, что, как я знаю, УЖАСНО, но единственный, работающий в Chrome. Если бы у кого-то из вас была идея, как лучше решить эту проблему, я был бы очень благодарен.источник
.ready()
гораздо лучшее и более элегантное решение.Меня удивляют все ответы здесь ...
Попробуй это:
window.setTimeout(function() { /* your stuff */ }, 0);
Обратите внимание на тайм-аут 0. Это не произвольное число ... как я понимаю (хотя мое понимание может быть немного шатким), есть две очереди событий javascript - одна для макро-событий и одна для микро-событий. Очередь с «большей» областью действия содержит задачи, которые обновляют пользовательский интерфейс (и DOM), а микро-очередь выполняет операции типа быстрой задачи.
Также имейте в виду, что установка тайм-аута не гарантирует, что код будет работать точно с указанным значением. По сути, это помещает функцию в более высокую очередь (ту, которая обрабатывает UI / DOM) и не запускает ее раньше указанного времени.
Это означает, что установка тайм-аута, равного 0, помещает его в UI / DOM-часть очереди событий javascript для запуска при следующей возможности.
Это означает, что DOM обновляется со всеми предыдущими элементами очереди (например, вставленными через
$.append(...);
, и когда ваш код запускается, DOM полностью доступен.(ps - я узнал об этом из Secrects of the JavaScript Ninja - отличной книги: 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Я столкнулся с той же проблемой и нашел простое решение. После вызова функции добавления добавьте готовый документ.
$("#root").append(child); $(document).ready(function () { // Action after append is completly done });
источник
Использование
MutationObserver
может действовать как обратный вызов дляappend
метода jQuery :Я объяснил это в другом вопросе , и на этот раз приведу пример только для современных браузеров:
// 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>');
источник
Я думаю, что на это хорошо дан ответ, но это немного более конкретно для обработки "subChild_with_SIZE" (если это исходит от родителя, но вы можете адаптировать его там, где это может быть)
$("#root").append( $('<div />',{ 'id': 'child' }) ) .children() .last() .each(function() { $(this).append( $('<div />',{ 'id': $(this).parent().width() }) ); });
источник
$.when($('#root').append(child)).then(anotherMethod());
источник
$.when
работает только для тех объектов, которые возвращают объект обещанияanotherMethod()
сразу .. Это не передается как обратный вызов.функция добавления Jquery возвращает объект jQuery, поэтому вы можете просто пометить метод в конце
$("#root").append(child).anotherJqueryMethod();
источник
Для изображений и других источников вы можете использовать это:
$(el).one('load', function(){ // completed }).each(function() { if (this.complete) $(this).load(); });
источник
Самый чистый способ - делать это шаг за шагом. Для обхода каждого элемента используйте функцию each. Как только этот элемент добавлен, передайте его следующей функции для обработки этого элемента.
function processAppended(el){ //process appended element } var remove = '<a href="#">remove</a>' ; $('li').each(function(){ $(this).append(remove); processAppended(this); });
источник
Я столкнулся с этой проблемой при кодировании 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> This p element </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();
Надеюсь это поможет!
источник
В jquery вы можете использовать сразу после добавления
$(function(){ //code that needs to be executed when DOM is ready, after manipulation });
$ () вызывает функцию, которая либо регистрирует обратный вызов, готовый к DOM (если ему передана функция), либо возвращает элементы из DOM (если ему передана строка селектора или элемент)
Здесь вы можете найти больше
различий между $ и $ () в jQuery
http://api.jquery.com/ready/
источник
Я знаю, что это не лучшее решение, но лучшая практика:
$("#root").append(child); setTimeout(function(){ // Action after append },100);
источник
$('#root').append(child); // do your work here
В приложении нет обратных вызовов, и это код, который выполняется синхронно - нет риска, что это НЕ будет выполнено.
источник
$('#root').append(child).anotherMethod();
источник