Завершение события касания с preventDefault

У меня было много:

$('#element').on('tap', function(){
    // some code ..
})

Я дважды искал много вопросов о проблеме с событием tap, и я решил проблему с помощью e.preventDefault(), теперь у меня много:

$('#element').on('tap', function(e){
    e.preventDefault();
    // some code ..
})

Хорошо, но, как я уже сказал, у меня есть много таких вызовов, и мне не нравится писать каждый раз e.preventDefault(), затем я набрал $.fn.tap на консоли Chrome и показал мне:

function (a){return a?this.bind(c,a):this.trigger(c)}

Я попытался переписать его следующим образом:

$.fn.tap = function (a) {
    a.preventDefault(); 
    return a?this.bind(c,a):this.trigger(c)
}

Но это не сработало, как в предыдущем e.preventDefault().

Я не вижу ничего очевидного, и у меня нет идей для этого.

Любая помощь или идея оцениваются. Спасибо заранее.

Ответ 1

Одна из интересных функций jQuery (я обычно не использую "jQuery" и "cool" в одном предложении) заключается в том, что он позволяет вам указать настраиваемое поведение для событий, используя объект $.event.special.

очень мало документации по этому вопросу, так что пример немного будет в порядке. Рабочая скрипка с использованием события click (как это было удобнее для меня писать на моем ноутбуке) можно найти здесь

Переведенный на ваш запрос, чтобы все события tap имели e.preventDefault(), вызываемые перед фактическим обработчиком, выглядели бы так:

$.event.special.tap.add = function(options) {
  var handler = options.handler;

  options.handler = function(e) {
    e.preventDefault();

    return handler.apply(this, arguments);
  }
}

Что делает этот код (должен делать, поскольку я на самом деле не тестировал версию tap выше), сообщает jQuery, что вы хотите специальное лечение для события tab, в частности, вы хотите предоставить "упаковку" обработчик ", который делает не более чем вызов e.preventDefault() перед вызовом предоставленного обработчика событий.

UPDATE: не удалось перезаписать настройки по умолчанию tap, для будущих посетителей


ПРИМЕЧАНИЕ. Прежде чем предпринимать какие-либо попытки изменить поведение вещей по умолчанию, вы должны спросить себя, почему настройки по умолчанию не работают для вас. В основном потому, что изменение поведения по умолчанию (= ожидаемое) нарушит ваше будущее (или, что еще хуже, другое лицо), при сохранении кода и добавлении функций.

Для создания поддерживаемого (и прогнозируемого) потока в вашем коде предлагаемое решение для создания специальной функции случая ($.fn.tap) на самом деле является очень жизнеспособным решением, так как оно не мешает по умолчанию (= ожидается ) поведение вещей.

Из приведенных ссылок вы также можете создать свой собственный тип события (например, tapOnly) и сделать его более очевидным, если есть какая-то специальная работа. Опять же, оба этих решения потребуют от вас изменить привязки событий, которые вы пытаетесь предотвратить.

Ответ 2

Вот как вы можете создать свой $.fn.tap: -

$.fn.tap = function(f) {
  $(this).on('tap', function(e) {
    e.preventDefault();
    f();
  });
  return this;
};

//usage
$('.selector').tap(function() {
  alert('foo bar')
})

@Washington Guedes - перезаписать событие-ответ по умолчанию, чтобы всегда использовать e.preventDefault() вместо изменения от $(element).on('tap', function() {}) to $(Элемент).TAP(функция() {})

Вы можете добавить событие делегата в body для tap, не указав цель. Затем он будет запускаться для всех событий tap на теле, которые затем вы можете проверить, имеет ли цель свое собственное событие tap, поэтому вы можете e.preventDefault();.

ПРИМЕЧАНИЕ. Это не будет работать для делегированных событий tap, как показано.

// global tap handler
$('body').on('tap', function(e) {
  if ($._data(e.target, "events").tap)
    e.preventDefault();
});

// tap event
$('a.tap').on('tap', function(e) {
  $(this).css('color', 'red');
});

// delegated tap event
$('body').on('tap', 'a.delegate', function(e) {
  $(this).css('color', 'green');
});
a {
  display: block;
  margin: 20px 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/mobile/1.4.5/jquery.mobile-1.4.5.js"></script>

<a class="tap" href="www.google.co.uk">tap event, prevented.</a>
<a class="delegate" href="www.google.co.uk">delegate tap event, not prevented.</a>
<a href="www.google.co.uk">no tap event, not prevented</a>

Ответ 3

Я знал, что это плохая идея, но я только что проверил это в Chrome

$('*').on('tap',function(e){
    e.preventDefault();
});

$('#element').on('tap', function(){
    // some code ..
});

и если вам это не нужно для всех элементов:

$('*').not('#aCertainElement').on('tap',function(e){
    e.preventDefault();
});

Ответ 4

У меня была аналогичная проблема, в которой e.preventDefault() работал бы в некоторых случаях, но не на других. Он не обнаружил ошибок, и использование try-catch не отображало catch alert. Добавление e.stopImmediatePropagation() выполнило трюк, если оно помогает кому-либо