E.preventDefault() не пуленепробиваемый?
Я задал аналогичный вопрос, но не получил настоящего удовлетворительного ответа, поэтому я попробую снова здесь. Когда я использую такой код:
$("#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!
} );
Я ожидаю, что событие click никогда никогда не запускается (из-за иерархии, с которой браузер должен работать через события), но на самом деле, когда я прикасаюсь к элементу, скажем 20 раз, чем один раз, когда срабатывает событие click, Почему?
И я также пробовал такие вещи, как:
$("#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;
} );
Казалось, что он немного прочный, но не пуленепробиваемый.
Поэтому я должен был сделать:
$("#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;
} );
который, похоже, работает, но ужасно глупо, не так ли? Кто-нибудь с идеями, о чем это? Спасибо!
EDIT:
Поэтому мне действительно нужно было сделать что-то вроде:
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
} );
Давай, ребята! Должен существовать безопасный общий способ использования событий touchstart и click на одном элементе, гарантирующий, что событие click не будет запущено (дважды), чтобы обрабатывать как сенсорные, так и обычные браузеры (или даже новые комбинированные). Как вы это сделаете?
Ответы
Ответ 1
Я ожидаю, что событие click никогда никогда не запускается (из-за иерархии, с которой браузер должен работать через события) [...]
У вас неправильные ожидания even.preventDefault()
.
event.preventDefault()
предотвращает действие по умолчанию, которое браузер выполняет для этой комбинации элементов/событий. Например. отправив форму или следующую ссылку. Он не предотвращает выполнение любого другого обработчика событий.
e.stopPropagation()
предотвращает буферизацию события, поэтому обработчики событий, добавленные к предкам, не выполняются.
Однако вы не можете использовать какой-либо из этих методов, чтобы предотвратить выполнение обработчиком другого события, поэтому установка флажка, действительно, является правильным способом для этого.
Ответ 2
Сейчас я использую следующий код в большинстве мест на моем сайте, который работает очень хорошо и надежно:
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 Это не мое изобретение, но, к сожалению, я забыл источник, потому что прошло какое-то время.