On iPhone 6, it seems that the mousedown event does not fire on document when it is tapped (but fires when its children is tapped due to event propagation).
Is this a bug or by design? Is there any easy workaround?
-- Edit --
It seems to fire for other elements like div and button (but not document).
It is expectable - there is no mouse on iPhone.
For touch devices use events touchstart and touchend:
$(document)
.on('touchstart', function(e){
})
.on('touchend', function(e){
});
You may also want to read this MDN article on Touch Events.
Related
To prevent a click from firing, you can call e.preventDefault() in a click event handler. This lets you bind an event to mousedown, see if something happens like the mouse moving a certain distance, and if so, prevent the click when the mouse button is released.
A click handler with e.preventDefault() does not seem to prevent a click on certain touch devices however. (I am testing on an iPad mini). I have also tried calling e.preventDefault() in the touchend handler, which seems to do nothing.
Calling e.preventDefault() in the touchstart blocks the page from scrolling, and is also useless because it is too early to tell if the click should be cancelled. Only touchmove can decide if a cancel needs to occur.
The issue is, when a user drags a draggable element which is also a link, it needs to cancel the "click" of the link on fingerup. This works just fine on a desktop by cancelling the click event.
Is there an equivalent event I can cancel that stops an "armed click" from going off once the user lifts their finger up?
iOS is known to not register the click event property. This is likely due to the fact that iOS waits a little longer to determine how a click should be interpreted as:
the start of a pinching/zooming gesture
two or multiple-finger panning
the start of scrolling
the start of double tapping
a simple tap event (which we are trying to capture)
the start of touch-and-hold
Therefore, you can listen to the tap event instead, included in jQuery Mobile.
The jQuery Mobile tap event triggers after a quick, complete touch
event that occurs on a single target object. It is the gesture
equivalent of a standard click event that is triggered on the release
state of the touch gesture.
The tap event is not native, because it relies on conditionally listening upon touchstart to determine if the start and stop targets are the same: if so, jQuery Mobiel determines that it is indeed a genuine tap event and fires the custom, non-native event tap. This logic can be seen in the original source file, at line 75 onwards of ./js/events/touch.js.
An example usage is as follow:
$(selector).on('tap', function(e){
e.preventDefault();
});
I have an Ember.View that handles both the click and touchEnd events, for both desktop and mobile interactions.
Unfortunately, touchEnd also gets fired when scrolling, which is not intended. How do I handle the click and tap, but avoid the scroll event?
Ember.View.extend({
click: function() {
// not handled in a mobile browser
},
touchEnd: function() {
// handled in a mobile browser, but unfortunately also on scroll
}
});
Instead of adding handlers for both click and touchEnd, use the fastclick library. Now you just need to add a handler for the click event. If your using ember-cli, there is an addon for this.
I have a scrollable list in my web app, using scrollability to deal with the overflow:scroll feature. although when I finish scrolling and take my finger out of the screen the event bellow also triggers.
$('li').live('touchend', function (e) {
//...
});
The thing is that I only would like this event above to fire when the action there's no touchmove event before that.
it is possible to suppress a touchend event from inside the touchmove event?
so it simulates better the iOS UITableView component? where when touchmove starts it cancels the target for touchend
Set a flag in touchmove which can be tested in touchend and if the flag is set, just skip the functionality and possibly preventDefault() (either way, reset the flag at the end).
On a Windows 7 computer with IE9 and a multitouch screen, like an HP TouchSmart, if you touch the screen on a page that is tall enough to have a scrollbar and move your finger up or down the page scrolls. This doesn't seem to fire any mousemove event. If you touch the screen and initially move left or right instead of up and down it does fire the mousemouse events.
I wan't to cancel this scrolling and cause the browser to invoke a normal mousemove event. Is this possible?
EDIT: There does not appear to be touch events in IE9 Does IE9 support Touch events on Windows 7?
EDIT 2:
A couple other points of interest about this. First is that browsers often fire a mousewheel event when scrolling is triggered by a gesture, this can often be caught and cancelled. Second is that in this particular case, you can prevent the scrolling on IE9 with this hack $(document).bind('mousedown mouseup click dblclick', function (e) { }); which as hacks sometimes do, does not make any sense to me - it may be possible to use fewer event bindings but I didn't have good access to a device to easily test.
After spending some time testing the various methods to suppress default event responses, I have no idea how to suppress the scroll event. You should, however, be able to fire the mousemove event from within a scroll event handler.
window.onscroll = function(e){
element.onmousemove();
}
//jquery
$(window).scroll(function(e){ element.mousemove(); } );
A primitive example.
Two things I suppose you could try to prevent auto-scroll: setting the overflow (or overflow-y) to hidden on you body element or as part of your onscroll handler, attempting to scroll back to your point of origin. Setting body's overflow to hidden will prevent scrolling and hide the scrollbar, but I'm not sure it's what you want.
Try touch events instead of mouse events.
I had the same issue with iPad. I had to add an e.preventDefault(); to the touchmove event. I did this only to the div where I was tracking interaction, not to the whole page.
element.ontouchmove = function(e){ e.preventDefault(); };
No idea about your device, but might be worth a try.
In trying to figure out the scroll position for a UIWebView, I'm attaching a listener in the HTML that will call back to the main app. I attach the javascript listener like:
window.onscroll = function reportScroll() {
var sY = window.pageYOffset;
alert('Scroll pos: '+sY); // Would evetually trigger a URL or something
}
This event only seems to be triggered at the end of a flick scroll on OS 3.2 (iPad), once the deceleration has ended. However this: https://developer.apple.com/library/content/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html#//apple_ref/doc/uid/TP40006511-SW7 seems to indicate that it should be triggered at the end of a single finger pan as well. I really need to know when that pan completes as well.
According to QuirksMode Safari iPhone doesn't fire onscroll event on window, but rather on the document (and any other element). I would bet Safari iPad does the same thing.
I experienced the same problem in iPhone as well: flick scroll correctly produces the onscroll event, but single finger panning does not (I was using this in my fixed menu implementation, where the menu is hidden after ontouchstart event, and restored after onscroll).
I solved the problem by using two parallel events: onscroll and ontouchend. They both refer now to the same event handler (that restores the menu). As events are suppressed during scroll, the ontouchend event does not get fired if the window continues the flick scrolling. Now the event handling works for both flick scroll and panning.
I have not tested this in iPad, I would be interested in knowing if this fix helps in that as well.
In iOS Safari, the onscroll event should be fired only once at the end of the scroll (after deceleration). If you are simply taking your finger off of the screen, think of it as instant deceleration. So if you are performing a 'flick scroll', the onscroll event is still only fired once, at the very end of deceleration.
It sounds like you should also monitor the touchend event:
$(window).on('touchend', function() {
// Do something
});
Note: The touchend event will be fired for each finger that is lifted off the screen.