Hammer events delegation and reuse of backbone view

谁都会走 提交于 2020-01-04 03:57:04

问题


Edit

According the Hammer Github page this bug was due to Manager leaks and should be fixed in the 2.0.5 version - this version is not built online but one can built it by himself. More info can be found here

=====================================================

Original question:

=====================================================

We are using Backbone with Hammer 2,backbone hammer plugin and hammer jquery plugin.

The issue

when working with domEvents and only 1 copy of A view it works fine.

But, when doing something like

var first = new A();
var second = new A();

hammer listeners do not work on the second view.

note: When adding click event to the list above, the click is being fired on both first and second views. So this something with hammer events and events delegations.

Any ideas how to overcome this issue ?

Thanks!

Oak

P.S Some code (run-able in stack-overflow)

Here is some code example. As can be seen - swiperight only works on the first view and not on the second. The code use touch emulator so one can check it with mouse as well.

A = Backbone.View.extend({

  hammerEvents: {

    "panstart .js-feed-btn": "_onPan",
    "panmove .js-feed-btn": "_onPan",
    "swiperight .js-feed-btn": "_onSwipeRight",
    "click .js-feed-btn-clickable": "_onClick"

  },

  hammerOptions: {
    //tap: true,
    domEvents: true
  },

  _onPan: function(e) {
    this.$el.find('.status-bar').html('panning... ' + this.cid);
    var view = this;
    if (this._animate) {
      return;
    }
    snabbt(e.target, {

      position: [e.originalEvent.gesture.deltaX / 2, 0, 0],
      duration: 100,
      callback: function() {
        this._animate = false;
      }

    })

  },

  _onSwipeRight: function(e) {
    snabbt(e.target, {
      position: [e.originalEvent.gesture.deltaX, 0, 0],

    }).then({
      position: [0, 0, 0]
    })


    this.$el.find('.status-bar').html('swiperight ' + this.cid);

  },


  _onClick: function() {
    this.$el.find('.status-bar').html('clicked ' + this.cid);
  },

  render: function() {
    this.$el.html('<div class="js-feed-btn">swipe me right</div><div class="js-feed-btn-clickable">clickme</div><section class="status-bar"></section>');
    return this;
  },

});


var first = new A();
var second = new A();

var parent = new Backbone.View();
parent.$el.append(first.render().$el)
parent.$el.append(second.render().$el)
  //$('.app').html(first.render().$el)
  //$('.app').append(second.render().$el)
$('.app').html(parent.$el)
div {
  min-height: 20px;
}
.status-bar {
  background-color: green;
  color: white;
}
<script src="https://rawgit.com/hammerjs/touchemulator/master/touch-emulator.js"></script>
<script>
  TouchEmulator();
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script src="https://hammerjs.github.io/dist/hammer.min.js"></script>
<script src="https://rawgit.com/jashkenas/underscore/master/underscore-min.js"></script>
<script src="https://rawgit.com/jashkenas/backbone/master/backbone-min.js"></script>
<script src="https://rawgit.com/hammerjs/jquery.hammer.js/master/jquery.hammer.js"></script>
<script src="https://rawgit.com/wookiehangover/backbone.hammer/master/backbone.hammer.js"></script>
<script src="https://rawgit.com/daniel-lundin/snabbt.js/master/snabbt.js"></script>
<section id="main">
  <h3>Simple code</h3>
  <section class="app"></section>

</section>

回答1:


I believe this is a bug, and I have tracked down the offending code. I will file a bug report and pull request next week (though I am not yet certain that my solution doesn't break something else).

The problem is that Hammer is adding all the listeners to the very first element (which incidentally results in your receiving an event for every element to which you add the recognizer--add 4 press listeners, and your callback gets called 4 times for every press).

I've managed to make press and swipe events work (with touch device emulation via Chrome, as well as a genuine iPad and a Nexus 7). Haven't tested other events yet.

I simply changed line 946 (of Hammer 2.0.4) from

this.evTarget = TOUCH_TARGET_EVENTS;

to

this.evEl = TOUCH_TARGET_EVENTS;

Note that you might need to make the same change to line 878, but I haven't actually figured out where, when or if the SingleTouchInput class is ever used.

Like I said, I'm not certain that this is a proper fix, but it is certainly a workaround. I'll report back if I discover any problems or undesirable side-effects.



来源:https://stackoverflow.com/questions/28722774/hammer-events-delegation-and-reuse-of-backbone-view

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!