Backbone.js click event doesn't work with touc

2019-01-23 17:15发布

问题:

events: 
    'click' : 'select'

When using this event on Mobile Safari the event gets triggered twice when touched. Is this a known bug or something that I am causing on my own?

I've since changed it to

events: 
    'touchstart' : 'select'

and it works great but means that it will not work in normal browsers anymore.

Thanks for any info.

回答1:

Try this code:

TouchView = Backbone.View.extend({
  events: function() {
    return MOBILE ? 
       {
         "touchstart": 'select'
       } : 
       {
         "mousedown": 'select'
       }
  }
}

See it in action: http://jsfiddle.net/dira/Ke2px/2/



回答2:

I have used Modernizr to detect the touch device and used following code and this worked for me.

events :function(){ 
   return Modernizr.touch ? 
     {
         "touchstart #edit" : "openEdit",
     }: 
     {
         "click #edit" : "openEdit",
     }
 }


回答3:

I've solved the same issue generically by creating backbone.touch for Backbone that will monkey patch Backbone.View to respond to touch events when a touch device is used, or regular click events when not.

You can either just include the source file to have it transform all of your click events in Backbone.Views, or you can take a peek at the code and implement it yourself.



回答4:

I defined both events types and it works for me on a mobile and desktop:

events: {
'click' : 'select',
'touchstart' : 'select'
}


回答5:

I'm not familiar with Backbone, but maybe try setting it conditionally?

if ('ontouchstart' in document.documentElement) {
  // 'touchstart': 'select'
} else {
  // 'click': 'select'
}


回答6:

I just include the jquery touchpunch library and that's it.

https://github.com/furf/jquery-ui-touch-punch



回答7:

Using coffeescript, I'd do the following, I don't ever find a reason to bring in modernizer when every mobile device these days is really a touch device, I mean when was the last time you had to really support something that didn't?

window.isTouchDevice =  (/android|webos|iphone|ipod|ipad|blackberry|iemobile/i.test(navigator.userAgent.toLowerCase()) )

  events: ->
    for k, v of this when /click/.test(k) and isTouchDevice
      mobileKey = k.replace('click','touchstart')
      events[ mobileKey ] = v
      delete events[ k ]
    return events

Coffeescript reads better for these type of list comprehensions imho.



回答8:

this worked for me.

events:{
  'click #edit':'select',
  'touchstart #edit':'select'
},
select: function(e){
  e.stopPropagation();
  e.preventDefault();
  console.log('open upload dialog ', e.type);
}

now when you test this if the device is touch e.type should be touchstart and only fire once. Same for click on no-touch device. In case anybody is still looking for a simple solution for this.