스크롤 이벤트가 사용자에 의해 생성되었는지 감지
스크롤 이벤트가 브라우저 또는 사용자에 의해 수행되었는지 알 수 있습니까? 특히 뒤로 버튼을 사용하면 브라우저가 마지막으로 알려진 스크롤 위치로 이동할 수 있습니다. 스크롤 이벤트에 바인딩하면 이것이 사용자 또는 브라우저에 의한 것인지 어떻게 알 수 있습니까?
$(document).scroll( function(){
//who did this?!
});
브라우저에서 스크롤을 일으키는 세 가지 유형의 상황이 있습니다.
- 사용자가 몇 가지 작업을 수행합니다. 예를 들어, 마우스 휠, 화살표 키, 페이지 위로 / 아래로 키, 홈 / 종료 키를 사용합니다.
- 브라우저가 자동으로 스크롤됩니다. 예를 들어 브라우저에서 뒤로 버튼을 사용하면 마지막으로 알려진 스크롤 위치로 자동으로 이동합니다.
- 자바 스크립트 스크롤. 예 :
element.scrollTo(x,y).
불행히도 직접 말할 수있는 방법은 없습니다.
이런 유형의 흐름에 의존하지 않도록 앱을 다시 디자인 할 수 있다면 그렇게하세요.
그렇지 않은 경우, 내가 생각할 수 있는 해결 방법 은 사용자가 시작한 스크롤을 추적하고 스크롤이 브라우저 또는 사용자에 의해 트리거되었는지 확인하는 것입니다.
다음은이 작업을 잘 수행하는 예제입니다 (jQuery 기록에 문제가있는 브라우저 제외).
완전히 테스트하려면 로컬에서 실행해야합니다 (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에 따라 다를 수 있으므로 적절하게 변경해야 할 수 있습니다.
도움이 되었기를 바랍니다!
내가 아는 한 "사용자"또는 다른 수단에 의해 스크롤 이벤트가 발생했을 때마다 알려주는 것은 (작업없이) 불가능합니다.
(다른 사람들이 언급했듯이) 마우스 휠 이벤트를 포착 한 다음 스크롤 (화살표, 공백 등)을 트리거 할 수있는 키에서 keydown 이벤트를 포착하려고 시도 할 수 있습니다. 예를 들어 스크롤 할 수 없기 때문입니다. 입력 필드에 입력하는 동안 화살표 키. 일반적으로 그것은 복잡하고 복잡한 스크립트입니다.
처리중인 상황에 따라 "논리 되돌리기"를 추측 할 수 있습니다. 사용자가 발행 한 스크롤 이벤트를 감지하는 대신 프로그래밍 방식으로 만든 스크롤에 연결하고 코드에서 만들지 않은 스크롤 이벤트를 사용자가 만든 것으로 처리합니다. 내가 말했듯이 상황과 달성하려는 목표에 따라 다릅니다.
예, 100 % 가능합니다. IE가 요구 사항이 아닌 클라이언트 전용 응용 프로그램에서 현재 사용하고 있습니다. 내 Backbone 앱이 스크롤이 변경되는 애니메이션을 시작할 때 스크롤이 발생하지만 이러한 이벤트 캡처를 트리거하지 않습니다. 이것은 FF, Safari 및 Chrome 최신 버전에서 테스트되었습니다.
$('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)) {
}
}
});
모든 사용자 이벤트를 잡으려고하는 것보다 반대의 작업을 수행하고 프로그래밍 방식 이벤트 만 처리하고 무시하는 것이 훨씬 쉽습니다.
For example, this kind of code would work:
// 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
});
Then when you call setScrollTop(), the scroll event will be ignored, while if the user scroll with the mouse, keyboard or any other way, the event will be processed.
Try using the Mousewheel and DOMMouseScroll events instead. See http://www.quirksmode.org/dom/events/scroll.html
You can check the scroll position on ready. When you fire the on scroll event check to make sure the scroll position is different than it was when the page loaded. Lastly be sure to clear out the stored value once the page is scrolled.
$(function () {
var loadScrollTop = ($(document).scrollTop() > 0 ? $(document).scrollTop() : null);
$(document).scroll(function (e) {
if ( $(document).scrollTop() !== loadScrollTop) {
// scroll code here!
}
loadScrollTop = null;
});
});
Found this very useful. Here's a coffeescript version for those so inclined.
$ ->
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;
if you're using JQuery than there's a better answer, apparently - i'm just trying it out myself.
see: Detect jquery event trigger by user or call by code
Regarding to:
Specifically, when using the back button a browser may jump to the last known scroll position.
That fires very soon, after the page is rendered. You can just delay listenting to the scroll event by 1 second or so.
There is one more way to separate the user-created scroll: you can use the alternative event handlers, for example 'mousewheel', 'touchmove', 'keydown' with codes 38 and 40 for arrow scrolling, for scrolling with scroll bar - if 'scroll' event is fired simultaneously with 'mousedown' until 'mouseup' event.
참고URL : https://stackoverflow.com/questions/7035896/detect-whether-scroll-event-was-created-by-user
'Nice programing' 카테고리의 다른 글
| OS X의 경로에서 / usr / bin 전에 / usr / local / bin을 갖는 데 문제가 있습니까? (0) | 2020.11.02 |
|---|---|
| 완전한 Cocos2d-x 튜토리얼 및 가이드 목록 (0) | 2020.11.02 |
| 퍼블릭 API의 리소스에 UUID를 사용해야합니까? (0) | 2020.11.02 |
| R 스크립트를 독립 실행 형 .exe 파일로 컴파일 하시겠습니까? (0) | 2020.11.02 |
| 코드 진단 구문 노드 작업이 닫힌 파일에서 작동하도록하려면 어떻게해야합니까? (0) | 2020.11.02 |