Сочетание jQuery Mobile taphold и jQuery UI с возможностью перетаскивания - PullRequest
6 голосов
/ 06 марта 2012

Я работаю над мобильным приложением, в котором я пытаюсь объединить перетаскиваемую функциональность пользовательского интерфейса jQuery с событием касания jQuery Mobile. Идея состоит в том, что элемент становится перетаскиваемым при выполнении метки.

Draggable инициализируется для элементов в следующем коде:

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

Как видите, функция перетаскивания изначально отключена, потому что я хочу включить ее после события касания. Для достижения этого в настоящее время я использую следующий код:

// 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');
}); 

Это работает, но проблема в том, что для перетаскивания элемента требуется событие «release-and-tap-again», а не перетаскивание сразу после события taphold. Может ли это быть какой-то проблемой вмешательства события? Я пробовал что-то вроде event.preventDefault(), но мои знания о событиях jQuery невелики, поэтому я понятия не имею, должно ли это иметь какое-то значение.

Есть идеи, как решить эту проблему?

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

Во-первых, jquery ui draggable не работает с сенсорными событиями. Я предполагаю, что вы внесли необходимые корректировки, чтобы это исправить.

т.е. см. Сортировка Jquery-ui не работает на сенсорных устройствах на базе Android или IOS

Далее, я бы сказал, что событие touchstart не проходит из-за того, как taphold был реализован в jquery mobile.

Перетаскивание будет инициировано только в том случае, если оно получит событие touchstart / mousedown.

Я видел нечто подобное раньше, но с двойной картой в сочетании с перетаскиваемым.

Вам может потребоваться вручную вызвать событие touchstart в вашем обработчике события taphold, чтобы перетаскиваемый элемент активировал:

$('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);
});
1 голос
/ 24 августа 2017

Хотя и немного поздно - я заставил это работать, пропустив плагин taphold и использовав его вместо этого. Не забудьте добавить 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);
});
...