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>
How 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 command? 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 completely rendered.
Related
I am trying to ascertain if it's possible to determine whether a scroll event was emitted simply due to a height change of an element, as opposed to a manual user scroll?
We are utilizing an internally developed UI library which displays a "toast" message on the page until it detects any user interaction, in this case, they have the following event listeners hooked up:
document.addEventListener("click", this.handleClose);
document.addEventListener("keydown", this.handleClose);
document.addEventListener("scroll", this.handleClose);
Unfortunately, if we dispatch one of these toast messages and then asynchronously load any content which changes the page size, a scroll event is emitted regardless of whether a user has actually scrolled or not. I've considered disabling the event from propagating, but we still would like a manual scroll to dismiss the toast message.
Any thoughts would be greatly appreciated.
I want to detect user if he is not using his computer by tracking mouse events? Do you know How can I achieve this using JQuery or Javascript?
Not sure tracking mouse movements outside the browser is possible. You track this type of thing by using event listeners and mounting the listener to an html element. in your case you would mount a mousemove listener to the window to track movement across the whole page. But outside of the browser window their is nothing that JS can mount an event listener to their for leaving no option to track mouse movement outside the browser. (could be wrong though, seems creepy if its possible)
I have a hopefully rather simple Javascript question for you. I have a scrollable, static page which can show/hide a full frame overlay (hiding the whole page) using z-index. When the overlay is shown I create a new event listener to "keydown" in which I for example check for "ArrowDown". When the overlay is hidden, the listener is unsubscribed.
This works beautifully, except that the page below the overlay keeps scrolling up and down as it normally would. I thought I could stop that by using
event.stopPropagation()
which, however, does not help. How can I approach this?
Event.stopPropagation() Prevents the event from bubbling up the DOM, but does not stop the browsers default behaviour.
event.preventDefault();
this should work as it stops the browsers default behaviour.
I have implemented the Swipe for Action Android pattern in my mobile web application (PhoneGap) using JavaScript & CSS animations/transitions.
However, there's one thing that's still eluding me.
I wish, that once the action menu is displayed fully and the user clicks anywhere outside of the action menu (labelled 3 in the figure), the menu should retract and the original item displayed (labelled 1 in the figure).
In a desktop application, one could "capture focus" and perform the transition back to (1) in lostfocus.
What is the JS equivalent of lostfocus event. I see an onfocus and onblur event, but from what I read it's really meant for things that need focus; like input, textarea, etc.
How else could I catch that event I'm interested in, other than putting some code in the touchend of every other element in the page and forcing the retraction of open actions explicitly?
I think you gave the answer yourself. focus and blur are the events to be used for this and they are not exclusively meant for input elements, as you can see here [1].
I'm even trigger the focus event manually in a layer use case: A layer opens and I want to capture the keypress of ESC to close the layer. For this I need to set the focus on the layer as my event handler would not fire otherwise.
To capture the click outside you just need to register for pointerUp or click events on an element that spans the whole screen (it must really cover the whole screen like the body element). Because of the event bubbling the handler will fire as long as nothing else captured and cancelled it.
[1] https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3-Events.html#event-type-blur
With the Prototype Javascript framework, you would write the following code to listen for the window scroll event.
document.observe(
'dom:loaded',
function() {
Event.observe(
window,
'scroll',
function(event) {
console.info(event);
}
);
}
);
On iOS's Safari browser, the scroll handler is no longer fired when you leave the page and hit back. Android's browser does not have this problem. Someone filed a solution for jQuery, but I use Prototype. How do you make sure you are always listening for the scroll event with Prototype?
Not sure what the details are in Prototype, but as far as mobile browser support for the traditional scroll event it does not exist. You will get a scroll event fired when the scrolling is determined to be over, which I have found to be awkward. If you dig into the jQueryMobile source code you will see how they dealt with it. For example the fixed position toolbars. They hide them anytime a touchstart event is fired. They do this because they have no concrete way to determine if the app is being scrolled or not. And since there is no event being fired as the view is being scrolled they do not know how to reposition the fixed toolbars. Once the scroll end event has fired or the touchend/touchstop/touchcancel event fires they redisplay the toolbar at the correct position.