Combining jQuery Mobile taphold and jQuery UI draggable

大憨熊 提交于 2019-12-21 12:37:41

问题


I'm working on a mobile application where I'm trying to combine jQuery UI's draggable functionality with jQuery Mobile's taphold event. The idea is that an element becomes draggable when a taphold is executed.

Draggable is being initialized on elements in the following code:

$('div.rect', '#outerBox').draggable({
    containment: "parent", 
    grid: [50, 50],
    disabled: true,
    stop: function(event, ui) {
        $(this).draggable('disable');
        $(this).removeClass('highlighted');
    }
}); 

As you can see the draggable functionality is disabled initially, because I want to enable it after a taphold event. To achieve this I'm currently using the following code:

// Bind long press event to rectangle elements
$('div.rect', '#outerBox').bind('taphold', function(event, ui) {
    // Enable dragging on long press
    $(this).addClass('highlighted');
    $(this).draggable('enable');
}); 

This works, but the problem is that a 'release-and-tap-again'-event is needed in order to drag the element around, instead of dragging directly after the taphold event. Could this be some kind of event-interference problem? I've tried things like event.preventDefault() but my knowledge of jQuery events isn't much so I have no idea whether or not this should make any difference.

Any idea on how to solve this one?


回答1:


First, jquery ui draggable does not work with touch events. I'm assuming you've made the nessesary adjustments to fix this.

I.e. see Jquery-ui sortable doesn't work on touch devices based on Android or IOS

Next I would say the touchstart event is not flowing through because of how taphold has been implemented in jquery mobile.

The draggable will only be initiated if it gets a touchstart/mousedown event.

I've seen something similar before, but with a doubletap in conjunction with a draggable.

You may need to manually trigger the touchstart event inside your taphold event handler for the draggable to kick in:

$('div.rect', '#outerBox').bind('taphold', function(event, ui) {
    var offset = $(this).offset();
    var type   = $.mobile.touchEnabled ? 'touchstart' : 'mousedown';
    var newevent = $.Event(type);
    newevent.which  = 1;
    newevent.target = this;
    newevent.pageX  = event.pageX ? event.pageX : offset.left;
    newevent.pageY  = event.pageY ? event.pageX : offset.top;

    $(this).trigger(newevent);
});



回答2:


Though a little late - I got this to work by skipping the taphold plugin and using this instead. Remember to add Touch Punch!

$('#whatever').on('touchstart', function (event) {
    var me = this;

    if (!me.touching) {
        if (me.touched) { clearTimeout(me.touched); };
        me.touched = setTimeout(function () {
            //console.log('taphold');

            //Prevent context menu on mobile (IOS/ANDROID)
            event.preventDefault();

            //Enable draggable
            $this.draggable('enable');

            //Set internal flag
            me.touching = true;

            //Add optional styling for user
            $(me).addClass('is-marked');

            //trigger touchstart again to enable draggable through touch punch
            $(me).trigger(event);

            //Choose preferred duration for taphold
        }, 500);
    }
}).on('touchend', function () {
    //console.log('touchend');
    this.touching = false;

    //Disable draggable to enable default behaviour
    $(this).draggable('disable');

    //Remove optional styling
    $(this).removeClass('is-marked');

    clearTimeout(this.touched);
}).on('touchmove', function () {
    //console.log('touchmove');

    clearTimeout(this.touched);
});


来源:https://stackoverflow.com/questions/9580574/combining-jquery-mobile-taphold-and-jquery-ui-draggable

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