furf / jquery-ui-touch-punch

A duck punch for adding touch events to jQuery UI
http://touchpunch.furf.com/
3.51k stars 1.33k forks source link

Click events inside draggable do not work #5

Closed jamesmehorter closed 12 years ago

jamesmehorter commented 13 years ago

If you create a draggable() element with child elements that have .click() the click function is not called by user tapping. I've added the touch-punch library after jquery ui, and verified that drag objects do indeed drag with touch events on the iPhone, but any child click() functions do not trigger when the user taps on the child element. The click() mouse event on computer still works as expected, just not on the mobile. Ideas?

jsd219 commented 13 years ago

I too am having this same issue. Anyone?

sohi87 commented 13 years ago

I have the same issue, I can't click any link inside the sortable grid. I need help regarding this.

dbashford commented 13 years ago

Add me to the list of folks confounded by this issue. I have a ton of draggables and also clickables. This super simple bit of code got drag-n-drop working real well, but won't be able to use it because it kills clicks on the iPad.

ghost commented 13 years ago

I too am having the same problem on my Android 2.2 phone. I got the dragging effect working on multiple elements, but once you start a drag, it interferes with clickable elements within the dragged container. Any ideas why? I will be glad to pursue them some workaround, as this is a real killer.

ghost commented 13 years ago

I have some code which for basic drag elements solves this problem. I added a click event monitor (borrowed from somewhere else). It seems to work, but there may be a better way to implement this for touch-punch. I'm in a little over my head here code wise. I have just started messing with touch events. Here is my code (as implemented for my needs). You will have to modify it back to just std. jQuery code to run it, but you should be able to pick out what was done to solve the click problem. I'm still refining this, but as I said, others should be better qualified to get this implement in touch-punch. This seems to work, but might still have some bugs related to propagation, etc.

// Copyright Notice: // touch_ui.js v4.0.0 // Copyright©2011 - OpenSiteMobile // All rights reserved // ========================================================================== // http://opensite.mobi // ========================================================================== // Contact Information: // Author: Dwight Vietzke // Email: dwight_vietzke@yahoo.com

/ OpenSiteMobile touch user interface /

/global msos: false, jQuery: false /

msos.provide("msos.touch_ui");

msos.touch_ui = { click_target: null, click_valid: false, click_cancel: function () { "use strict"; msos.touch_ui.click_target = null; msos.touch_ui.click_valid = false; } };

// mouse over event then mouse down msos.touch_ui.touch_start = function (event) { "use strict";

var temp_tch = 'msos.touch_ui.touch_start -> ',
first = event.originalEvent.changedTouches[0],
simulatedEvent = null;

if (msos.config.debug) { msos.console.debug(temp_tch + 'start.'); }

// Mouse over first
simulatedEvent = document.createEvent("MouseEvent");
simulatedEvent.initMouseEvent(
"mouseover", true, true, window, 1,
first.screenX, first.screenY,
first.clientX, first.clientY,
    false, false, false, false, 0, null
);
first.target.dispatchEvent(simulatedEvent);

msos.touch_ui.click_target = first.target;
msos.touch_ui.click_valid = true;
window.setTimeout(msos.touch_ui.click_cancel, 600);

if (msos.config.debug) { msos.console.debug(temp_tch + 'done!'); }

};

/! ** Most of below is std Touch Punch w/ hooks for above ***

(function ($) { "use strict";

if (!msos.config.browser.touch) {
    msos.console.warn('msos.touch_ui -> browser does not support touch!');
    return;
}

var mouseProto  = $.ui.mouse.prototype,
    _mouseInit  = mouseProto._mouseInit,
    _mouseDown  = mouseProto._mouseDown,
    _mouseUp    = mouseProto._mouseUp,

    mouseEvents = {
        touchstart: 'mousedown',
        touchmove:  'mousemove',
        touchend:   'mouseup'
    };

function makeMouseEvent(event) {

    var touch = event.originalEvent.changedTouches[0];

    return $.extend(event, {
        type:    mouseEvents[event.type],
        which:   1,
        pageX:   touch.pageX,
        pageY:   touch.pageY,
        screenX: touch.screenX,
        screenY: touch.screenY,
        clientX: touch.clientX,
        clientY: touch.clientY
        }
    );
}

mouseProto._mouseInit = function () {

    var self = this;

    self.element.bind('touchstart.' + self.widgetName, function (event) {

    // Process only one touch events for jQuery UI
    if (event.touches && event.touches.length > 1) {
            if (msos.config.debug) {
                msos.common.event_debug(event, 'touchstart.' + self.widgetName + ' -> skipped multi-touch');
            }
    return true;
    }

        event.preventDefault();

    // Set mouseover and click processes
    msos.touch_ui.touch_start(event);

    return self._mouseDown(makeMouseEvent(event));
    });

    _mouseInit.call(self);
};

mouseProto._mouseDown = function (event) {

    var self = this;

    self._touchMoveDelegate = function (event) {
        event.preventDefault();
        return self._mouseMove(makeMouseEvent(event));
    };

    self._touchEndDelegate = function(event) {

    var first = event.originalEvent.changedTouches[0],
    simulatedEvent = null;

    // Terminate propagation of touchend
    event.preventDefault();

    // If touchend happens before "click_cancel', fire a click event
    if (msos.touch_ui.click_valid
     && first.target === msos.touch_ui.click_target) {

    simulatedEvent = document.createEvent("MouseEvent");

    simulatedEvent.initMouseEvent(
        "click", true, true, window, 1,
        first.screenX, first.screenY,
        first.clientX, first.clientY,
        false, false, false, false, 0, null
    );

    first.target.dispatchEvent(simulatedEvent);

    if (msos.config.debug) {
        msos.console.debug('_touchEndDelegate -> fired click event.');
    }
    return true;
    }

    // Otherwise, just do the normal touch-punch stuff
        return self._mouseUp(makeMouseEvent(event));
    };

    self.element
        .bind('touchmove.' + self.widgetName, self._touchMoveDelegate)
        .bind('touchend.'  + self.widgetName, self._touchEndDelegate);

    return _mouseDown.call(self, event);
};

mouseProto._mouseUp = function (event) {

    var self = this;

    self.element
        .unbind('touchmove.' + self.widgetName, self._touchMoveDelegate)
        .unbind('touchend.'  + self.widgetName, self._touchEndDelegate);

    return _mouseUp.call(self, event);
};

}(jQuery));

furf commented 12 years ago

Latest update should have fixed this issue. Please try it and let me know if you have any further issues. Thanks for the feedback!

kamelkev commented 12 years ago

I have a surprisingly similar problem to the one described above, however I am using 0.2.2, going to create a new ticket for it as whatever the cause of the previous issue may be different than this one

lavermil commented 7 years ago

I solved the problem my using one of the forks. Specifically the version of his I am using is 0.4.0. I have only played with draggable and click on hrefs. Both work when previously using 0.2.3 from furf only draggable worked.

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

niranjanadhikari commented 3 years ago

@lavermil

This is working (draggable + clickable) in mobile but it's not sortable anymore.

$(function () {
    $(".img-rack:not(#img-upload-rack), .vid-rack").sortable({
      helper : 'clone',
            start: function (event, ui) {
                    ui.item.toggleClass("highlight");
            },
            stop: function (event, ui) {
                    ui.item.toggleClass("highlight");
            }
    });
    $(".img-rack:not(#img-upload-rack), .vid-rack").disableSelection();

});

RWAP commented 3 years ago

Rather than commenting on a thread which was closed in 2017 (!) I would suggest reading the issues first.

You will find that this code has not been updated since 2014, and there is a new version at:

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

This seems to be working for nearly everyone!

hassanrazadev commented 3 months ago

I solved the problem my using one of the forks. Specifically the version of his I am using is 0.4.0. I have only played with draggable and click on hrefs. Both work when previously using 0.2.3 from furf only draggable worked.

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

Excellent! I was looking for this from last 5+ hours... Finally its over...