[jquery] .append 후 jQuery 함수

jQuery .append가 완전히 완료된 후 함수를 호출하는 방법 은 무엇입니까?

예를 들면 다음과 같습니다.

$("#root").append(child, function(){
   // Action after append is completly done
});

문제 : 복잡한 DOM 구조가 추가되면 추가 함수 콜백 내에서 루트 요소의 새 크기 계산이 잘못되었습니다. DOM은 아직 완전히로드되지 않았으며 추가 된 복잡한 DOM의 첫 번째 자식 만로드된다는 가정입니다.



답변

여기에 유효한 답이 많이 있지만 그 중 어느 것도 실제로 작동하는 이유를 알려주지 않습니다.

JavaScript에서 명령은 시간 초과 또는 간격을 사용하여 명시 적으로 비 동기화하도록 지시하지 않는 한 순서대로 동기식으로 한 번에 하나씩 실행됩니다.

즉, .append메서드가 실행되고 해당 메서드가 작업을 완료 할 때까지 다른 어떤 것도 실행되지 않습니다 (존재할 수있는 잠재적 인 제한 시간 또는 간격에 관계없이).

요약하면 .append동 기적으로 실행 되므로 콜백이 필요하지 않습니다 .


답변

Marcus Ekwall은 추가의 동시성에 대해 절대적으로 옳지 만, 이상한 상황에서 다음 코드 줄이 실행될 때 브라우저에서 DOM이 완전히 렌더링되지 않는 경우도 있음을 발견했습니다.

이 시나리오에서 shadowdiver 솔루션은 .ready를 사용하여 올바른 라인을 따르지만 호출을 원래 추가에 연결하는 것이 훨씬 깔끔합니다.

$('#root')
  .append(html)
  .ready(function () {
    // enter code here
  });


답변

크기 재계 산과 똑같은 문제가 있으며 몇 시간 동안 두통을 겪은 후에는 .append()엄격하게 동기식 으로 행동하는 것에 동의하지 않습니다 . 적어도 구글 크롬에서는. 다음 코드를 참조하십시오.

var input = $( '<input />' );
input.append( arbitraryElement );
input.css( 'padding-left' );

padding-left 속성은 Firefox에서 올바르게 검색되지만 Chrome에서는 비어 있습니다. 내가 생각하는 다른 모든 CSS 속성과 마찬가지로. 몇 가지 실험 후 나는 CSS ‘getter’를 setTimeout()10ms 지연 으로 래핑하는 데 안주해야 했지만 지옥처럼 추악하지만 Chrome에서 작동하는 유일한 것입니다. 이 문제를 더 나은 방법으로 해결하는 방법에 대한 아이디어가 있다면 매우 감사하겠습니다.


답변

여기에있는 모든 답변에 놀랐습니다 …

이 시도:

window.setTimeout(function() { /* your stuff */ }, 0);

0 시간 초과에 유의하십시오. 그것은 임의의 숫자가 아닙니다 … 내가 이해하는 바와 같이 (내 이해가 약간 흔들릴 수 있지만) 두 개의 자바 스크립트 이벤트 큐가 있습니다. 하나는 매크로 이벤트 용이고 다른 하나는 마이크로 이벤트 용입니다. “큰”범위의 대기열은 UI (및 DOM)를 업데이트하는 작업을 보유하고 마이크로 대기열은 빠른 작업 유형 작업을 수행합니다.

또한 시간 제한을 설정한다고해서 코드가 지정된 값에서 정확히 수행되는 것은 아닙니다. 이것이하는 일은 본질적으로 함수를 더 높은 큐 (UI / DOM을 처리하는 큐)에 넣고 지정된 시간 전에 실행하지 않는 것입니다.

즉, 시간 제한을 0으로 설정하면 자바 스크립트 이벤트 큐의 UI / DOM 부분에 배치되어 다음 가능한 기회에 실행됩니다.

즉, DOM이 이전의 모든 대기열 항목 (예 :를 통해 삽입 됨)으로 업데이트되고 $.append(...);코드가 실행될 때 DOM을 완전히 사용할 수 있습니다.

(ps- Secrects of the JavaScript Ninja 에서 배웠습니다 -훌륭한 책 : https://www.manning.com/books/secrets-of-the-javascript-ninja )


답변

누군가에게 유용 할 수있는 또 다른 변형이 있습니다.

$('<img src="http://example.com/someresource.jpg">').load(function() {
    $('#login').submit();
}).appendTo("body");


답변

나는 같은 문제를 발견하고 간단한 해결책을 찾았습니다. 추가 기능을 호출 한 후 문서를 준비합니다.

$("#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>');