#javascript #jquery #callback #hammer.js
#javascript #jquery #обратный вызов #hammer.js
Вопрос:
Я пытаюсь включить некоторые сенсорные элементы управления с помощью функции обратного вызова, но у меня возникают проблемы с доступом к событию, а также к $ (this) в моей функции обратного вызова. Прямо сейчас код выглядит следующим образом:
$('.img-responsive').each(touchControls);
function touchControls(event) {
event.preventDefault();
var mc = new Hammer(this);
mc.on("doubletap", function() {
console.log($(this));
});
}
Где ‘.img-responsive’ — это класс изображений на моей странице.
Когда он пытается вызвать event.preventDefault, я получаю сообщение об ошибке, что event.preventDefault не является функцией. Я думал, что событие автоматически передается вызываемой переменной? Я знаю, что когда я выполнял именованную функцию обратного вызова с помощью .on, event.preventDefault() работал отлично. Я предполагаю, что это отличается, когда я делаю это с помощью .each, как мне правильно получить к нему доступ?
Теперь, если я удалю строку event.preventDefault(), когда она регистрирует $(this), я получаю функцию. Я ожидал получить отдельные элементы, чтобы я мог установить для них сенсорное управление, но это явно не сработало. Я попытался связать «это» с помощью:
$('.img-responsive').each(touchControls).bind(this);
Но когда я зарегистрировал $ (this), это все еще была функция, а не элемент, который я ожидал.
Я в основном просто запутался в том, как получить доступ к $ (this) и событию в определенной функции обратного вызова.
Ответ №1:
.each
не является обработчиком событий, поэтому его функция обратного вызова не принимает event
объект. Сигнатура метода each
функции обратного вызова выглядит следующим образом:
.каждый (функция)
функция
Тип: Функция (целочисленный индекс, элемент элемента )
Функция для выполнения для каждого соответствующего элемента.
Таким образом, у вас не будет event
объекта для ссылки, но, что более важно, не будет никакого поведения события по умолчанию для предотвращения.
И наоборот, on
фактически настраивает обработчики событий. Его функция обратного вызова принимает событие в качестве своего параметра. Вы можете управлять своими событиями в своем коде обработчика событий, внутри функции обратного вызова для .on
.
this
будет ссылаться на ваш текущий элемент при выполнении итерации. Но внутри вашей внутренней функции обратного вызова будет другой контекст (то есть другой this
). Просто сохраните ссылку на элемент во внешней области:
function touchControls() {
var $this = $(this);
var mc = new Hammer(this);
mc.on("doubletap", function(e) {
e.preventDefault();
console.log($this);
});
}
Комментарии:
1. В этом случае, как мне предотвратить увеличение масштаба события doubletap по умолчанию? Если я не должен предотвращать это здесь, то где мне получить к нему доступ, чтобы предотвратить это?
2. @MichaelYousef обновил мой ответ, чтобы обратиться к управлению событиями.
3. Я предполагаю, что Hammer изменяет контекст, чтобы это указывало на функцию для doubletap? Несмотря на это, ваше решение сработало, так что спасибо.
4.@MichaelYousef Это не столько
Hammer
изменение контекста, сколько он естьon
. Из документов: «Когда jQuery вызывает обработчик,this
ключевое слово является ссылкой на элемент, в который доставляется событие; для непосредственно связанных событий это элемент, к которому было присоединено событие» В вашем случае обработчик привязанmc
, так что это то, чтоthis
относится.
Ответ №2:
У вас событие передается в неправильной функции.. Вам нужно передать его в прослушиватель событий. Первым аргументом каждого цикла является текущий индекс итерации.
$('.img-responsive').each(touchControls);
function touchControls(eachIndex) {
var mc = new Hammer(this);
mc.on("doubletap", function(event) {
// move preventDefault here and pass the event
event.preventDefault();
console.log($(this));
});
}
function Hammer(el){
return $(el)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="img-responsive">img</div>
<div class="img-responsive">img</div>