views:

996

answers:

4

I'm looking for a super simple jQuery extension. Basically I need to use some events that jQuery does not explicitly support. These events are the iPhone touch events like ontouchstart, ontouchend, and ontouchmove.

I have it working via this:

// Sucks
$('.clickable').each(function() {
  this.ontouchstart = function(event) {
    //do stuff...
  };
}

Which kind of sucks and is unjqueryish. Here is what I would like:

// Better
$('.clickable').touchstart(function() {
  //do stuff...
}

Or even better with 1.4

// Awesome
$('.clickable').live('touchstart', function() {
  //.. do stuff
}

These events need no special handling and should work just like any other events, but I can't seem to figure out how to extend jquery to make them work just like all the other events do.

A: 

jQuery.com is a great source of information like this.

If you build your own plugin you'll be able to use whatever naming you like on your method calls.

TreeUK
I was hoping to simply piggy back all the existing event handling and just add support for a few more event types. There is nothing special about these that would require special handling beyond what click or mousedown do.
Squeegy
+1  A: 

Here's a start:

$.fn.touchstart = function(fn) { return this[fn ? "bind" : "trigger"]("touchstart", fn); };
$.event.special.touchstart = {
    setup: function() {
        $.event.add(this, "mouseenter", extendedClickHandler, {});
    },
    teardown: function() {
        $.event.remove(this, "mouseenter", extendedClickHandler);
    }
};

Where extendedClickHandler is the function that does what it's suppose to do.

More info here: http://brandonaaron.net/blog/2009/03/26/special-events

jerone
A: 

I wrote the plugin, if the user does have touch available, use, otherwise, call click

jQuery.event.special.tabOrClick = {
                setup: function (data, namespaces) {
                    var elem = this, $elem = jQuery(elem);

                    if (window.Touch) {
                        $elem.bind('touchstart', jQuery.event.special.tabOrClick.onTouchStart);
                        $elem.bind('touchmove', jQuery.event.special.tabOrClick.onTouchMove);
                        $elem.bind('touchend', jQuery.event.special.tabOrClick.onTouchEnd);
                    } else {
                        $elem.bind('click', jQuery.event.special.tabOrClick.click);
                    }
                },

                click: function (event) {
                    event.type = "tabOrClick";
                    jQuery.event.handle.apply(this, arguments);
                },

                teardown: function (namespaces) {
                    if (window.Touch) {
                        $elem.unbind('touchstart', jQuery.event.special.tabOrClick.onTouchStart);
                        $elem.unbind('touchmove', jQuery.event.special.tabOrClick.onTouchMove);
                        $elem.unbind('touchend', jQuery.event.special.tabOrClick.onTouchEnd);
                    } else {
                        $elem.unbind('click', jQuery.event.special.tabOrClick.click);
                    }
                },

                onTouchStart: function (e) {
                    this.moved = false;
                },

                onTouchMove: function (e) {
                    this.moved = true;
                },

                onTouchEnd: function (event) {
                    if (!this.moved) {
                        event.type = "tabOrClick";
                        jQuery.event.handle.apply(this, arguments)
                    }
                }
            };

            $("#xpto").bind("tabOrClick", function () {
                alert("aaaa");
            });
Alexandre
A: 

This now works, just like it's stubbed out above, on the latest jQuery release. Go jQuery!

Squeegy