Как остановить распространение() с Hammer.js 2.0?

У меня есть родительский и дочерний div. Панорамирование/перетаскивание дочернего элемента не должно влиять на родителя. Это аналогичный вопрос, но он был задан год назад, и я использую более новую версию Hammer.js с оболочкой jQuery.

Мое предположение состояло в том, что мне нужно было бы каким-то образом остановить распространение(), но я не совсем уверен, как его использовать.

Я смоделировал демонстрацию, показывающую мою проблему с JsFiddle. Я также прокомментировал пару вещей, которые я пробовал.

$(".outer-box").hammer().bind("panright", function(event){
    // do stuff when panning
    // panning here should move both boxes
});
$(".outer-box").hammer().bind("panend", function(event){
    // do stuff when panning ends
});

$(".inner-box").hammer().bind("panright", function(event){
    // do stuff when panning
    // panning here should only affect the inner box
});
$(".inner-box").hammer().bind("panend", function(event){
    // do stuff when panning ends
});

Любые предложения или советы? Спасибо!


person Eric    schedule 24.09.2014    source источник


Ответы (7)


В Hammer 2.0.6, как ответили другие, вы можете позвонить event.srcEvent.stopPropagation(). Одно предостережение, вы должны установить domEvents=true в соответствии с документацией.

Hammer может запускать события DOM с параметром domEvents: true. Это даст вам такие методы, как stopPropagation(), так что вы сможете использовать делегирование событий. Hammer не будет отвязывать связанные события.

Образец кода

var mc = new Hammer.Manager(elem);
mc.options.domEvents=true; // enable dom events
var pinch = new Hammer.Pinch();
mc.add(pinch);
mc.get('pinch').set({ enable: true });
mc.on("pinch",function(e){e.srcEvent.stopPropagation();});

or

var hammertime = new Hammer(elem);
hammertime.domEvents = true;
hammertime.on("panstart", function(e){e.srcEvent.stopPropagation();});

Этот метод указан на странице советов в документации, здесь http://hammerjs.github.io/tips/< /а>

person gtzilla    schedule 23.08.2016

Попробуйте event.srcEvent.stopPropagation(). Hammer оборачивает себя вокруг собственного объекта события; srcEvent дает вам доступ к «обычным» возможностям объекта события.

person mlehmeher    schedule 01.11.2014

У меня была та же проблема, в частности, вложенный компонент Hammer не останавливал распространение должным образом. В моем случае я хотел, чтобы модальный контейнер (который был родительским компонентом самого высокого уровня, полноэкранный с непрозрачным черным фоном) обрабатывал событие щелчка, закрывающее все модальное окно. Дочерние компоненты содержат содержимое, и я хотел отменить распространение этих дочерних элементов. Другими словами, желаемое поведение: щелчок внутри модального окна ничего не делает, но щелчок вне модального окна закрывает модальное окно.

Это еще больше усложняется библиотекой react-hammerjs, которая добавляет дополнительный уровень абстракции, включая потенциальные отчеты об ошибках. которые указывают на неправильное распространение события.

Что бы я ни делал, я не мог заставить stopPropagation() работать. Даже если для options.domEvents установлено значение true. Я также безуспешно пытался копаться в event.srcEvent.stopPropagation() (и вариантах).

Я обнаружил, что использование stopImmediatePropagation() работает по назначению, независимо от настройки domEvents. Я понимаю, что stopImmediatePropagation() может быть более экстремальным, но у меня нет побочных эффектов. Обработчики кликов внутри дочерних элементов (например, кнопки) по-прежнему работают нормально, и я могу отменить модальное окно, щелкнув контейнер.

Вот мой последний фрагмент, который отлично работает:

const myComponent = (props) => (
   <Hammer onTap={() => { ... cancel modal ... }} >
      <div className={'modal-container'} >
         <Hammer onTap={(e) => e.srcEvent.stopImmediatePropagation()}>
            <div className={'modal-content'}>
               ... modal content
               <Hammer onTap={() => { ... button handler ... }}>
                  <button>Take Action</button>
               </Hammer>
            </div>
         </Hammer>
      </div>
   </Hammer>
)
person Blaine    schedule 28.09.2017
comment
stopImmediatePropagation у меня работало, когда только stopPropagation не было. Спасибо! - person Cully; 14.03.2019
comment
Сначала мне показалось, что stopImmediatePropagation тоже работает. Но это закончилось побочными эффектами, которые я не мог объяснить. После того, как он был вызван один раз, обработчик внешнего элемента не сработает, даже если он должен был перехватывать другие клики. В итоге я не использовал его, а установил новое свойство в srcEvent, которое более высокий уровень мог бы искать, когда оно всплывает. В одном смысле чище, в другом не очень. Теперь мне нужно стандартизировать это новое свойство для любого уровня выше. Но ключевым моментом было получение обработчиков, зарегистрированных в правильном порядке. Спасибо. - person WeakPointer; 03.01.2020

К сожалению, stopPropagation() не работает. Вам нужно проверить цель вашего жеста, чтобы понять, откуда было запущено событие.

Например:

$(parent_element).hammer().bind(gesture_type, function(event) {
    if (event.gesture.target.className === correctClass)
        doStuff();
});
person dom    schedule 10.03.2015

Это просто работает:

$(".outer-box").hammer({
  preventDefault: true,
  domEvents: true
}).on("panright", function() { });
person Angry Bird    schedule 10.12.2016

У меня была аналогичная ситуация, когда у меня было два контейнера, которые можно было перелистнуть друг над другом, и я хотел, чтобы событие обрабатывалось только верхним. По какой-то причине event.srcEvent.stopPropagation просто не работал.

Как оказалось, существует библиотека, которая расширяет Hammer.js с помощью распространения событий, называемого propagating-hammerjs. . Я втянул это в свой проект, это решило мою проблему.

person JavaSplice    schedule 18.04.2016
comment
Это ужасно, я перестану использовать HammerJs - person br4nnigan; 10.09.2018

Была такая же проблема, однако удалось справиться с этим, включив domEvents.

Hammer.defaults.domEvents = true;

После включения event.stopPropagation(); работал нормально.

person Sean    schedule 05.06.2017