问题
I have asked a similar question but didn’t get a real satisfying answer, so I will try again here. When I use code like this:
$("#element") .on( 'click', function() {
// do something
} )
.on( 'touchstart', function(e) {
e.preventDefault();
// do the same thing but on touch device like iPad f.e.
// and more over PLEASE do not fire the click event also!
} );
I am expecting that the click event is never never never fired (because of the hierarchy with which browser should work through the events) but in fact when I touch the element let’s say 20 times, than one time the click event fires also. Why?
And I also tried things like:
$("#element") .on( 'click', function() {
// do something
} )
.on( 'touchstart', function(e) {
e.preventDefault();
e.stopPropagation();
// do the same thing but on touch device like iPad f.e.
// and more over PLEASE do not fire the click event also!
return false;
} );
It seemed to be a little more solid but not bulletproof. So I had to do:
$("#element") .on( 'click', function() {
if ( !touchdevice ) {
// do something
};
} )
.on( 'touchstart', function(e) {
e.preventDefault();
e.stopPropagation();
// do the same thing but on touch device like iPad f.e.
// and more over PLEASE do not fire the click event also!
return false;
} );
which seems to work but is awfully silly, isn’t it? Anyone with ideas what is this about? Thanks!
EDIT: So I really had to do something like:
var touched;
$("#element") .on( 'click', function() {
if ( !touched ) {
// do something
};
} )
.on( 'touchstart', function(e) {
e.preventDefault(); // actual senseless here
e.stopPropagation(); // actual senseless here
touched = true;
// do the same thing but on touch device like iPad f.e.
// and more over PLEASE do not fire the click event also!
return false; // actual senseless here
} );
Come on guys! There must be a safe common way to use touchstart and click events on the same element ensuring that the click event is not fired (twice) to handle both touch sensible and regular browsers (or even the new combined ones). How would you do it?
回答1:
I am expecting that the click event is never never never fired (because of the hierarchy with which browser should work through the events) [...]
You have wrong expectations of even.preventDefault()
.
event.preventDefault()
prevents the default action that the browser performs for that element/event combination. E.g. submitting a form or following link. It does not prevent any other event handler from being executed.
e.stopPropagation()
prevents the event from bubbling up so that event handlers added to ancestors are not executed.
However, you cannot use any of these methods to prevent the handler of a different event to be executed, so setting a flag seems indeed to be the right way to do this.
回答2:
Right now I am using the following code in most places on my site which works very good and reliable:
var flag = false;
$("#element").on( 'touchstart click', function() {
if ( !flag ) {
flag = true;
setTimeout( function() {
flag = false;
}, 100 ); // someone else recommended 300 here but I use this value
// action here
};
return false;
} );
PS That is not my invention, but unfortunately I forgot the source because some time has passed.
来源:https://stackoverflow.com/questions/25671053/e-preventdefault-not-bulletproof