I'd like to have a handler fire whenever the user scrolls, but I don't want it to happen when the browser scrolls on behalf of the user. For example, the document below scrolls itself as part of onload. This fires my onscroll handler, but I don't want it to. Even if I remove the onload, there's still a problem: if the user scrolls and then reloads the page, the handler fires upon reload. Again, I don't want that.
Can the handler detect who caused it to be fired?
<html>
<body onscroll="alert('scroll detected')"
onload="window.scrollBy(0, document.height)">
aaa<br/>bbb<br/>ccc<br/>ddd<br/>eee<br/>fff<br/>ggg<br/>hhh<br/>iii<br/>
jjj<br/>kkk<br/>lll<br/>mmm<br/>nnn<br/>ooo<br/>ppp<br/>qqq<br/>rrr<br/>
sss<br/>ttt<br/>uuu<br/>vvv<br/>www<br/>xxx<br/>yyy<br/>zzz
</body>
</html>
I'd like to have a handler fire whenever the user scrolls, but I don't want it to happen when the browser scrolls on behalf of the user. For example, the document below scrolls itself as part of onload. This fires my onscroll handler, but I don't want it to. Even if I remove the onload, there's still a problem: if the user scrolls and then reloads the page, the handler fires upon reload. Again, I don't want that.
Can the handler detect who caused it to be fired?
<html>
<body onscroll="alert('scroll detected')"
onload="window.scrollBy(0, document.height)">
aaa<br/>bbb<br/>ccc<br/>ddd<br/>eee<br/>fff<br/>ggg<br/>hhh<br/>iii<br/>
jjj<br/>kkk<br/>lll<br/>mmm<br/>nnn<br/>ooo<br/>ppp<br/>qqq<br/>rrr<br/>
sss<br/>ttt<br/>uuu<br/>vvv<br/>www<br/>xxx<br/>yyy<br/>zzz
</body>
</html>
Share
Improve this question
asked Feb 12, 2009 at 19:57
mikemike
49.3k45 gold badges104 silver badges117 bronze badges
1
- Did any of these answers below help? – DMCS Commented Feb 23, 2009 at 23:54
4 Answers
Reset to default 3How about setting a (boolean) flag whenever you move the screen programmatically, and unsetting again, when the move is finished? Then your scroll-listener would first check against that flag, and make its actions based on that?
On examining the result of an action only (the document has been scrolled), you can't determine what cause the action.
Examining a change in state of certain properties before and after an action will help you in determining the cause of the action, assuming such relevant properties change differently depending on the cause of the change.
You should consider properties that may be relevant to the action of scrolling a document, and then consider how these properties may change:
- as a result of a document being scrolled
- when a person performs the scrolling
- when a browser performs the scrolling
When a person scrolls a document they may:
- hit a key (down arrow, up arrow, page down, page up, ctrl-end, ctrl-home)
- move the pointer to the scrollbar, click around a bit, move away from the scrollbar
The following event pattern would indicate a person scrolling:
- a scroll-relevant key is pressed OR the mouse moves off the browser canvas (on to the scrollbar)
- the document scrolls
In the case of a browser performing the action, the document merely scrolls without any preceding relevant key or mouse event.
In observing what happens before a scroll event occurs, you should be able to determine if the action was initiated by a person. Whilst this certainly may be tricky to implement, the logic is sound.
In short: you can't
Although, doing something like this with the help of a javascript library such as Prototype would be very easy using custom events:
<script language="javascript">
document.observe('user:scrolling', function() { alert('yay!'); });
</script>
...
<body onscroll="document.fire('user:scrolling')">
How about adding the onscroll
event during the document.onReady
event, instead of inline on the body mand? I think this should allow for the browser to scroll to the position, before you've added the onScroll
event.
Another option is to add a setTimeout()
to call a function to add the onscroll
event a few hundred milliseconds after the document is pletely rendered.