2014-09-05 4 views
4

스크롤 이벤트에서 javascript에 관한 이상한 것을 알게되었습니다.이벤트 콜백 전에 interval 함수가 실행되는 이유는 무엇입니까?

지금까지 스크롤 위치가 변경 될 때마다 직접 해고 될 것이라고 확신했습니다.
자바 스크립트가 블로킹하기 때문에 콜백이 항상 실행되고 첫 번째 기능이이 새로운 값을 "보게"됩니다.

여기 간단한 설정이 있습니다. 여기서 전역 값은 스크롤의 현재 스크롤 위치로 업데이트됩니다. 두 개를 비교하는 간격이 있습니다.
매우 빠르게 스크롤하면 캐시 된 값이 실제 반환 된 스크롤 위치와 같지 않은 경우가 종종 발생합니다.

// cache scroll pos 
var scrollPos = 0; 
// update on scroll 
window.onscroll = function() { 
    scrollPos = scrollTop(); 
}; 
// compare on interval 
setInterval(function() { 
    if (scrollPos != scrollTop()) { 
     console.log("Out of sync! cached:", scrollPos, "| actual:", scrollTop()); 
    } 
}, 100); 

바이올린 : 당신은 신속하게 주위로 스크롤 버튼을 사용하여 시도 할 수 있습니다 http://jsfiddle.net/71vdx4rv/2/
. [Chrome, Safari, FF, Opera에서 테스트]

콜백이 수행되기 전에 간격 기능이 실행되고 '새'스크롤 위치를 알고있는 이유는 무엇입니까?
누군가 나에게 설명해 주시겠습니까?

+0

onscroll이 계속해서 실행되지 않으므로 타이머가 업데이트 사이에서 실행할 수 있습니다. – epascarello

+0

아니요, 이것이 원인이 아닙니다. 물론 타이머는 업데이트 사이에서 실행할 수 있지만 항상 스크롤 이벤트 콜백 후 새 스크롤 pos 값을 가질 것이라고 생각했습니다. 이유가 무엇인지 알 수있는 대답을 참조하십시오. –

+0

야, 내 의견은 베르 기가 말한 것의 일반적인 요지이다. onscroll! == 페이지의 실제 이동과 1 대 1의 관계로, 이는 지속적인 플로우 업 업데이트가 아님을 의미합니다. 예. – epascarello

답변

4

지금까지 스크롤 위치가 변경 될 때마다 나는 항상 직접 실행될 것이라고 확신했습니다.

불행히도 (분명히) 그렇습니다. 문서보기 또는 요소가 스크롤되면 DOM 3 does state

동안 사용자 에이전트 [scroll] 이벤트를 전달해야한다. 이 이벤트 유형은 스크롤이 발생한 후 전달됩니다.

이것은 "즉시"를 의미하지 않습니다. CSSOM draft clarifies :

[스크롤을 수행하려면, 반복 다음 단계를 실행] :

  1. positionbox의 [부드럽게 또는 인스턴트] 스크롤을 수행합니다.
  2. task을 실행하는 작업이 대기열에 없으면 task을 실행하도록 작업 대기열을 지정하십시오.

"작업 큐"

명시 적 이벤트가 비동기 적으로 전달되는 것을 의미한다 [task는 각각의 대상에 scroll 이벤트가 발생하지된다, 그래서 스크롤 위치가 이미있을 수 있습니다 스크롤 이벤트가 발생하기 전에 대기 태스크 (타이머와 같은)가 실행될 때 변경되었습니다.

부드러운 스크롤을 수행 할 때 브라우저는 임의의 시간 간격에 걸쳐 스크롤 위치를 여러 번 변경 한 다음 작업을 대기열로 두어 scroll 이벤트를 발생시킵니다.

+0

아주 좋은 대답, 고마워. –

관련 문제