2009-09-06 2 views
16

현재 내 프로그램은 사용자가 특정 요소를 스크롤하는 것을 청취하는 지점에 있지만이 요소를 자동으로 스크롤합니다."scrollLeft"/ "scrollTop"이 스크롤 이벤트 리스너를 트리거하지 않음을 변경합니다.

scrollLeft 또는 scrollTop을 설정하여 스크롤이 수행 된 경우 스크롤 이벤트가 트리거되지 않게 할 수 있습니까? 예를 들어, 내 생각에 기본 스위치는 다음과 같습니다.

ignoreScrollEvents = true; 
element.scrollLeft = x; 
ignoreScrollEvents = false; 

function onScroll() { 
    if(ignoreScrollEvents) return false; 
} 

이벤트가 즉시 트리거되지 않기 때문에 (oops, duhh) 효과가있는 해결책은 아닙니다. 어떤 다른 종류의 대답을 시도 할 수 있습니까? 그게 도움이된다면 jQuery도 사용하고 있습니다.

답변

17

가장 쉬운 일반적인 방법을 ? 이벤트 처리기에서 플래그를 재설정하면됩니다. 실제로 값을 변경하는 경우 먼저 확인해야합니다. 그렇지 않으면 이벤트가 실행되지 않습니다. Rodrigo notes과 같이이 항목을 소위 "설정자"기능에 포함시키는 것이 좋습니다.

function setScrollLeft(x) 
{ 
    if (element.scrollLeft != x) 
    { 
    ignoreScrollEvents = true; 
    element.scrollLeft = x; 
    } 
} 

... 

function onScroll() 
{ 
    var ignore = ignoreScrollEvents; 
    ignoreScrollEvents = false; 

    if (ignore) return false; 

    ... 
} 

그러나 필요에 따라 이미 스크롤 위치를 어딘가에 저장할 수 있습니다. 그렇다면 업데이트하여 플래그로 확인하십시오. 예 :

element.scrollLeft = currentScrollLeft = x; 

... 

function onScroll() 
{ 
    // retrieve element, etc... 

    if (element.scrollLeft == currentScrollLeft) return false; 

    ... 
} 
+0

코드에서 한 가지 문제가 발생합니다. 가끔씩 scrollLeft가 이미 0 인 경우, 코드가 0으로 설정하기도합니다. 따라서 스크롤 이벤트가 발생하지 않고 다음 사용자 스크롤이 무시됩니다. (이것은 홈, 엔드 등으로 스크롤하는 경우에만 실제로 문제가됩니다.) 그러나 이것은 확실히 가까운 해결책입니다. 그리고 나는 더미 구현에서 무언가 어리석은 것을 알았습니다. 감사! – Matchu

+0

그 점에 대해 궁금해했습니다. 그때 가장 좋은 방법은 깃발을 설정하기 전에 값을 변경하는지 확인하는 것입니다. 그렇지 않은 경우 플래그를 설정하지 마십시오.이미이 코드를 별도의 함수로 분해 할 수는 있지만 그렇게하지 않으면 그렇게하는 것이 더 쉬울 것입니다. 예를 들어 Rodrigo의 대답을 참조하십시오. – Shog9

1

당신 수 constantly check 경우 scroll position 변경 ...

+0

그것은 꽤 해결책은 아니지만 이벤트가 즉시 트리거되지 않는다고 말하는 경우 ... – marcgg

+0

이벤트가 즉시 트리거되지 않는다고 할 때 나는 일반적으로 그 것을 의미합니다. 첫 번째 세 줄을 실행하면 스크롤 이벤트가 트리거 될 때까지 모든 줄이 생깁니다. 자바 스크립트가 작동하는 방식이기 때문입니다. – Matchu

+0

이 솔루션은 허용 된 솔루션보다 예쁘다고 생각합니다. 허용 된 솔루션은 전역 변수를 만들기를 원하고 두 개의'onScroll' 핸들러를 원할 때마다 중단됩니다. 그러나이 솔루션은 탁월한 UX를 제공하지 않으므로 모든 곳의 바위와 어려운 곳입니다. – jcarpenter2

0

당신 수 당신이 onScroll들이시 귀하의 요소의 오프셋 (offset) 상단을 저장하고 scrollTop에 대해 그것을 일치 시도 :

function onScroll(){ 
    var scrollTop = (document.documentElement.scrollTop || document.body.scrollTop), 
    offsetTop = $('selector').offset().top; 
    if(offsetTop > scrollTop){ 
     //user has not scrolled to element so do auto scrolling 
    } 
} 
2

세터는 어떨까요?

var _preventEvent = false; // set global flag 
 

 
function setScrollTop(amount) { 
 
    _preventEvent = true; // set flag 
 
    document.documentElement.scrollTop = amount * Math.random(); 
 
} 
 

 
function setScrollLeft(amount) { 
 
    _preventEvent = true; // set flag 
 
    document.documentElement.scrollLeft = amount * Math.random(); 
 
} 
 

 
// scroll event listener 
 
window.onscroll = function() { 
 
    console.clear(); 
 
    
 
    if (_preventEvent) { 
 
    _preventEvent = false; // reset flag 
 
    return; 
 
    } 
 
    
 
    console.log('normal scroll'); 
 
}
html{ height:500%; width:500%; } 
 
button{ position:fixed; } 
 
button + button{ top:50px; }
<button onclick=setScrollTop(1000)>Random scrollTop</button> 
 
<button onclick=setScrollLeft(1000)>Random scrollLeft</button>

0

좋아, 내 최종 솔루션, Shog9 떨어져 구축 (나의 실제 코드,하지만 내 방식) :

var oldScrollLeft = element.scrollLeft; 
element.scrollLeft = x; 
if(element.scrollLeft != oldScrollLeft) { 
    ignoreScrollEvents = true; 
} 

function onScroll() { 
    if(!ignoreScrollEvents) performGreatActions(); 
    ignoreScrollEvents = false; 
} 

문은 무시 플래그를 설정하는 경우 실제로 scrollLeft 값이 변경되면 0에서 0으로 설정하는 것과 같이 플래그가 잘못 설정되지 않습니다.

감사합니다.

+0

그래서 정답은? – Rodrigo

+0

확실하지 않습니다. 여기 프로토콜은 뭐니? 대답의 일부를 사용하고 전체 답변에 도달하기 위해 구축하면 내 자신이나 다른 사람을 표시합니까? – Matchu

+0

허용 된 답변이이 경고를 포함하도록 편집되었으므로 이제이 답변과 일치합니다. – Matchu

관련 문제