append() 를 사용해 동적으로 생성한 요소에 스크롤 감지 이벤트가 적용이 안됨.
$target.append($ulElement)
// 생략
$('.scroll_ul').on('scroll', function () {
console.log('스크롤 위치:', $(this).scrollTop());
});
새로운 요소 append이후
아래처럼 실행해주니 해당 요소를 잡아 이벤트가 실행된다.
$target.append($ulElement)
// 생략
setTimeout(() => {
$('.scroll_ul').on('scroll', function () {
console.log('스크롤 위치:', $(this).scrollTop());
});
}, 0);
자바스크립트는 단일 스레드 기반으로 아래의 순서로 코드가 처리되기 때문.
- 동기(Synchronous) 코드 → 위에서 아래로 한 줄씩 실행
- 비동기(Asynchronous) 코드는 따로 대기 → 이벤트 루프가 다음 타이밍에 실행
$target.append($ulElement) // 동기 실행
// 생략
$('.scroll_ul').on('scroll', function () {
console.log('스크롤 위치:', $(this).scrollTop());
});
DOM을 조작했지만, 그 변경이 브라우저에 반영되기 전에 .on('scroll', ...)이 실행
.append()를 하더라도 자바스크립트는 브라우저에 DOM 변경 요청만 할 뿐,
브라우저가 실제로 DOM을 렌더링하는 시점은 자바스크립트 실행이 끝난 뒤!!
비동기 코드인 setTimeout(..., 0)은 현재 실행 컨텍스트가 모두 비워진 이후 실행되기 때문에
브라우저가 DOM 업데이트 및 렌더링을 완료한 이후 호출된다.
$target.append($ulElement)
// 생략
// DOM 완성된 다음 실행 보장
setTimeout(() => {
$('.scroll_ul').on('scroll', function () {
console.log('스크롤 위치:', $(this).scrollTop());
});
}, 0);
따라서, 현재 실행 중인 모든 동기 코드가 끝난 뒤 실행되기 때문에
추가된 대상 요소를 정상적으로 인식하고 이벤트 바인딩이 이루어진다.
(참고)
setTimeout(fn, 0)
가능한 한 빠르게, 현재 작업(콜스택) 이후 실행.
setTimeout(fn, 1)
최소 1ms 이후 실행. ( 실제론 보통 4ms 이상 )
setTimeout(fn, 1000)
1000ms(1초) 후에 실행.
(출력 예시)
console.log("A");
setTimeout(() => {
console.log("B");
}, ms);
console.log("C");
[ 실행순서 ]
- "A" 출력 (동기)
- setTimeout(..., ms) → 브라우저에 "ms 뒤 실행해줘" 요청 → task queue에 등록 ( ms 이후 등록 )
- "C" 출력 (동기)
- 콜 스택이 비면 이벤트 루프가 task queue에서 console.log("B")를 꺼내 실행 (콜 스택에 넣음)
- "B" 출력
'JavaScript > 공부공부' 카테고리의 다른 글
| [JS / jQuery] 커스텀 select-option 디자인 (0) | 2025.10.18 |
|---|---|
| [JS] URL 객체 (0) | 2025.07.15 |
| [JS] event.currentTarget vs event.target (0) | 2025.02.27 |
| [JS] Form & Checkbox (2) | 2024.11.06 |
| [JS] Property vs Attribute (0) | 2024.11.06 |