emberjs-addons / ember-touch

A lightweight library for building and using touch gestures with Ember Applications
MIT License
182 stars 28 forks source link

Enable an easy way to map tapEnd event to click #12

Open rykov opened 11 years ago

rykov commented 11 years ago

I've been looking around how to trigger {{action}} with both click and tapEnd to avoid the infamous 300ms onClick delay. The discussion at emberjs/ember.js#586 suggests using:

customEvents: { touchend: "click" }

Unfortunately, that unintentionally triggers buttons at the end of swipes, pinches, scrolls, etc.

So the question is, is there a way to detect an un-handled tapEnd event and re-trigger it as a click? Would this be a good feature to add to ember-touch?

ppcano commented 11 years ago

Regarding your purpose, first take a look at TapGestureRecognizer, perhaps the following options can work:

1) implement tapCancel method on your views. 2) create a custom gesture recognizer.

In my case, instead of using action helper, i created either a view mixin or extend the view funcionality and extend the view helper to work easily with click/tap events, anyway try to find a solution which fits best your use case.

Sometimes, it is useful to know in which environment your APP is running.

Em.OnClickAndTouch = 'ontouchstart' in window && 'onclick' in window;
rykov commented 11 years ago

I like the idea of having an agnostic application where the framework figures out the best way to handle a particular environment (convention over configuration). I think I'll take your advice and try to override the 'action' handlebars helper to default to "tapEnd" events on touch platforms instead of "click"

ghost commented 11 years ago

In the latest master, i've generated the doc's nad saw that for tap-events, you can now do something like this:

var myview = Em.View.create({ elementId: 'gestureTest',

tapEnd: function(recognizer, evt) { $('#gestureTest').css('background','yellow'); } });

This is good stuff but I also would like to do something like this:

{{action "pointerup" this on="click tapEnd"}}

in a template.

Wouldn't this be sensible? As far as I can see this is not possible yet.

ppcano commented 11 years ago

@vanthome, this is not possiblle, however you can override action helper to fit your case as @rykov pointed.

Sproutcore/Ember touch provides an advanced API to manage/build gestures in your App, if you want only to use tapEvents (as click events ), perhaps you don't need the whole project and can hack emberViews or action to helper to implement tap actions.

@rykov, which was your custom solution you finally choose?

rykov commented 11 years ago

No easy way - there are all sorts of issues with double counting clicks, or not counting at all which vary across browsers. The issues I encountered were:

I can expand on the above points, if you're interested about details. I've tried FastClick, but it still suffers from many of the issues above.

ghost commented 11 years ago

thx for your replies!

My goal is a solutoin that addresses the 300ms delay and I don' think this is the case with overriding the action helper. Can you confirm this @rykov ?

FastClick was my fallback solution but it is not a clean solution for use within ab ember application because it does not integrate with the whole event driven MV* concepts. Even worse I think when used in combination with ember touch I suspect undesired results.

@ppcano considering the issues rykov pointed out and the fact that there is already a tapEnd recognizer which works on views, I don't quite understand why it isn't sensible to provide this? Is it because ember doesn't offer respective extension points?

ppcano commented 11 years ago

@vanthome, when you import the project, it adds a gestureManager in views to manages only touchEvents passed by Ember EventDispatcher.

Regarding your questions, you could create your own gestureRecognizer, and you could extend Ember functionality with reopen & reopenClass methods.

I guess, your views are responding to both type of events "touch and click". You could implement somewhere that your views does not respond to click events in touch environments and if it requires, you could customize or define a new TapGestureRecognizer or customize the existing one.

ghost commented 11 years ago

@ppcano actually I'm fine with the already existing tapEnd gesture, I already tested it on a programatically created view as shown in my first post. What I'm struggling with however is to make it available in handlebars templates to use it like so:

{{action "pointerup" this on="click tapEnd"}}

do you have any hint how I could hack this (mayber later offering it for pull)?

ppcano commented 11 years ago

Take a look at emberjs/ember.js#605. I guess, whenever the project become more mature, perhaps core-team would pronounce a convention for that.

{{action "pointerup" this on="click" gestures="tap" }} makes more sense to me. However, gestures are created in the view constructor, and i think, the action helper does not create any view, so, i am not sure at all, but it wouldn't be possible in this way.

I have been using a custom view and extending view helper to manage this situation.

arcreative commented 11 years ago

I just found a wonderful fix by mistake. I'm doing most of my testing in Chrome before deploying to Android/iOS via PhoneGap. I opted for jquery mobile's touch implementation because it seemed a little more simple for basic events (no pinch/pan, etc.). I used the following to avoid unwanted double-click behavior due to the tap AND click events registering:

App = Ember.Application.extend({
    customEvents: {
        tap: "click",
        click: null //Prevent tap from registering as two clicks
    }
});

This registers the tap as a click and the click as nothing, so the double-click nonsense I was encountering is no longer an issue. It has the added advantage of working with the standard action handlers as well, so someone might want to give this a shot to see if it works.

rykov commented 11 years ago

This is very elegant - I'll try it out :+1:

mlb5000 commented 10 years ago

This works like a charm.

HamptonMakes commented 9 years ago

This broke for me... :(