programing

스크롤 이벤트가 사용자에 의해 작성되었는지 여부 탐지

batch 2023. 9. 13. 22:25
반응형

스크롤 이벤트가 사용자에 의해 작성되었는지 여부 탐지

스크롤 이벤트가 브라우저에 의해 이루어졌는지 사용자에 의해 이루어졌는지 알 수 있습니까?특히, 뒤로 버튼을 사용할 때 브라우저는 마지막으로 알려진 스크롤 위치로 점프할 수 있습니다.스크롤 이벤트에 바인딩할 경우 사용자 또는 브라우저로 인해 발생한 것인지 어떻게 알 수 있습니까?

$(document).scroll( function(){ 
    //who did this?!
});

브라우저에서 스크롤을 일으키는 세 가지 유형의 상황이 보입니다.

  1. 사용자가 몇 가지 작업을 수행합니다.예를 들어 마우스 휠, 화살표 키, 페이지 업/다운 키, 홈/엔드 키, 스크롤 막대를 클릭하거나 엄지손가락을 끕니다.
  2. 브라우저가 자동으로 스크롤됩니다.예를 들어 브라우저에서 뒤로 버튼을 사용하면 마지막으로 알려진 스크롤 위치로 자동으로 이동합니다.
  3. 자바스크립트 스크롤.를 들면면,element.scrollTo(x,y).

유감스럽게도 그것을 직접적으로 말할 수 있는 방법은 없습니다.

이런 흐름에 따라 달라지지 않도록 앱을 다시 디자인할 수 있다면 그렇게 해보세요.

그렇지 않다면 사용자가 시작한 스크롤을 추적하여 스크롤이 브라우저에 의해 트리거되었는지 사용자에 의해 트리거되었는지 확인하는 방법이 있습니다.

이것을 꽤 잘 수행하는 예는 다음과 같습니다(jQuery history에 문제가 있는 브라우저는 제외).

완전하게 테스트하려면 이를 로컬에서 실행해야 합니다(jsFiddle/jsbin은 iFrame 컨텐츠로 적합하지 않습니다).

제가 검증한 테스트 케이스는 다음과 같습니다.

  • 로드 - -userScroll이다 ㅇfalse
  • - /하여 -userScroll가 되다true
  • 하세요 - 하려면 합니다 를 으로 합니다 를 하려면 으로 .userScroll가 되다false
  • 뒤로뒤로가기 - 로/으로 - 를 합니다.userScroll가 되다false;

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <meta charset="utf-8" /> 
    <script src="http://code.jquery.com/jquery-1.6.1.min.js"></script> 
    <script type="text/javascript" src="https://raw.github.com/tkyk/jquery-history-plugin/master/jquery.history.js"></script> 
</head> 
<body> 
    <span> hello there </span><br/> 
    <a href="#bottom"> click here to go down </a> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/> 
    <a name="bottom"> just sitting </a> 
</body> 
<script type="text/javascript"> 

var userScroll = false;     

function mouseEvent(e) { 
    userScroll = true; 
} 


$(function() { 

    // reset flag on back/forward 
    $.history.init(function(hash){ 
        userScroll = false; 
    }); 

    $(document).keydown(function(e) { 
        if(e.which == 33        // page up 
           || e.which == 34     // page dn 
           || e.which == 32     // spacebar
           || e.which == 38     // up 
           || e.which == 40     // down 
           || (e.ctrlKey && e.which == 36)     // ctrl + home 
           || (e.ctrlKey && e.which == 35)     // ctrl + end 
          ) { 
            userScroll = true; 
        } 
    }); 

    // detect user scroll through mouse
    // Mozilla/Webkit 
    if(window.addEventListener) {
        document.addEventListener('DOMMouseScroll', mouseEvent, false); 
    }

    //for IE/OPERA etc 
    document.onmousewheel = mouseEvent; 


    // to reset flag when named anchors are clicked
    $('a[href*=#]').click(function() { 
        userScroll = false;
    }); 

      // detect browser/user scroll
    $(document).scroll( function(){  
        console.log('Scroll initiated by ' + (userScroll == true ? "user" : "browser"));
    });
}); 
</script> 
</html>

주의:

  • 사용자가 마우스로 스크롤 막대를 끌면 스크롤이 추적되지 않습니다.이것은 제가 연습을 위해 남겨둔 코드와 함께 추가될 수 있습니다.
  • event.keyCodesOS에 따라 다를 수 있으므로 이를 적절하게 변경해야 할 수도 있습니다.

도움이 되길 바랍니다!

모든 사용자 이벤트를 잡으려고 하는 것보다 반대의 작업을 수행하고 프로그래밍 방식의 이벤트만 처리하는 것이 훨씬 쉬워집니다.

예를 들어, 다음과 같은 코드가 작동합니다.

// Element that needs to be scrolled
var myElement = document.getElementById('my-container');

// Flag to tell if the change was programmatic or by the user
var ignoreNextScrollEvent = false;

function setScrollTop(scrollTop) {
    ignoreNextScrollEvent = true;
    myElement.scrollTop = scrollTop
}

myElement.addEventListener('scroll', function() {
    if (ignoreNextScrollEvent) {
        // Ignore this event because it was done programmatically
        ignoreNextScrollEvent = false;
        return;
    }

    // Process user-initiated event here
});

setScrollTop(), 또는 방법으로 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,

스크롤 이벤트가 "사용자"에 의해 또는 다른 방법으로 발행된 경우 언제든지 (작업 없이) 알 수 없는 것으로 알고 있습니다.

예를 들어 입력 필드를 입력하는 동안 화살표 키를 사용하여 스크롤할 수 없으므로 현재 포커스된 요소를 확인하는 동안 마우스 휠 이벤트를 캡처한 다음(다른 사람이 언급한 것처럼) 마우스 휠 이벤트를 캡처할 수 있습니다.일반적으로 그것은 복잡하고 지저분한 대본일 것입니다.

사용자가 처리하는 상황에 따라 "논리를 되돌린다"고 추측할 수 있습니다. 사용자가 발행한 스크롤 이벤트를 탐지하는 대신 프로그램적으로 만들어진 스크롤에 연결하고 코드에 의해 만들어지지 않은 스크롤 이벤트는 사용자가 만든 것으로 처리하면 됩니다.내가 말했듯이 상황에 따라, 그리고 당신이 무엇을 달성하려고 하는지에 따라 달라요.

네, 100% 가능합니다.저는 현재 IE가 필수 사항이 아닌 클라이언트 전용 애플리케이션에서 이 기능을 사용하고 있습니다.내 Backbone 앱이 스크롤이 변경되는 애니메이션을 시작하면 스크롤이 발생하지만 이러한 이벤트 캡처는 트리거하지 않습니다.이것은 FF, 사파리 & 크롬 최신 버전에서 테스트되었습니다.

$('html, body').bind('scroll mousedown wheel DOMMouseScroll mousewheel keyup', function(evt) {
  // detect only user initiated, not by an .animate though
    if (evt.type === 'DOMMouseScroll' || evt.type === 'keyup' || evt.type === 'mousewheel') {
    // up
    if (evt.originalEvent.detail < 0 || (evt.originalEvent.wheelDelta && evt.originalEvent.wheelDelta > 0)) { 
    // down.
    } else if (evt.originalEvent.detail > 0 || (evt.originalEvent.wheelDelta && evt.originalEvent.wheelDelta < 0)) { 
  }
}
}); 

대신 Mousewheel 및 DOMouseScroll 이벤트를 사용해 보십시오.http://www.quirksmode.org/dom/events/scroll.html 참조

준비된 상태에서 스크롤 위치를 확인할 수 있습니다.온 스크롤 이벤트를 실행할 때 스크롤 위치가 페이지가 로드되었을 때와 다른지 확인합니다.마지막으로 페이지가 스크롤되면 저장된 값을 지워야 합니다.

$(function () {
    var loadScrollTop = ($(document).scrollTop() > 0 ? $(document).scrollTop() : null);
    $(document).scroll(function (e) {
        if ( $(document).scrollTop() !== loadScrollTop) {
            // scroll code here!
        }
        loadScrollTop = null;
    });
});

관련 내용:

특히, 뒤로 버튼을 사용할 때 브라우저는 마지막으로 알려진 스크롤 위치로 점프할 수 있습니다.

페이지가 렌더링된 후 곧 실행됩니다.스크롤 이벤트 청취를 1초 정도만 지연시켜도 됩니다.

사용자가 만든 스크롤을 분리하는 또 다른 방법이 있습니다. 예를 들어 '마우스휠', '터치 무브', '키다운' 코드 38과 40을 가진 대체 이벤트 핸들러를 화살표 스크롤에 사용할 수 있습니다. 만약 '스크롤' 이벤트가 '마우스업' 이벤트까지 '마우스다운'과 동시에 발생한다면 스크롤 바로 스크롤할 수 있습니다.

아주 유용한 것을 발견했습니다.그렇게 마음이 가는 사람들을 위한 커피 대본 버전이 있습니다.

$ ->
  S.userScroll = false

  # reset flag on back/forward
  if $.history?
    $.history.init (hash) ->
      S.userScroll = false

  mouseEvent = (e)->
    S.userScroll = true

  $(document).keydown (e) ->
    importantKey =  (e.which == 33 or        # page up
      e.which == 34 or    # page dn
      e.which == 32 or    # spacebar
      e.which == 38 or    # up
      e.which == 40 or    # down
      (e.ctrlKey and e.which == 36) or    # ctrl + home
      (e.ctrlKey and e.which == 35)    # ctrl + end
    )
    if importantKey
      S.userScroll = true;

  # Detect user scroll through mouse
  # Mozilla/Webkit
  if window.addEventListener
      document.addEventListener('DOMMouseScroll', mouseEvent, false);

  # for IE/OPERA etc
  document.onmousewheel = mouseEvent;

JQuery를 사용하는 것보다 더 나은 답이 있습니다. 제가 직접 시도해 보는 겁니다.

참조: 사용자별 jquery 이벤트 트리거 탐지 또는 코드별 호출

응용 프로그램에 도움이 되지 않을 수도 있지만 사용자 스크롤에서 이벤트를 실행해야 했지만 다른 사용자에게 도움이 될 경우 프로그램 스크롤 및 게시는 실행할 수 없었습니다.

들어보세요.wheel대신 이벤트scroll,

사용자가 마우스 휠이나 트래커 패드를 사용할 때마다 트리거되며(대부분의 사용자가 스크롤하는 방식이라고 생각합니다) 프로그램으로 스크롤할 때는 발생하지 않습니다.사용자 스크롤 동작과 스크롤 기능을 구분하기 위해 사용했습니다.

https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event


element.addEventListener('wheel', (event) => {
       //do user scroll stuff here
})

한가지 주의할 점은wheel모바일에서는 스크롤에서 불이 안나와서 기기가 모바일인지 확인하고 비슷한 기능을 사용했습니다.

if(this.mobile){
  element.addEventListener('scroll', (event) => {
       //do mobile scroll stuff here
  })
}

언급URL : https://stackoverflow.com/questions/7035896/detect-whether-scroll-event-was-created-by-user

반응형