2012-03-06 10 views
6

Sto lavorando a un'applicazione mobile in cui sto cercando di combinare la funzionalità trascinabile di jQuery UI con l'evento taphold di jQuery Mobile. L'idea è che un elemento diventa trascinabile quando viene eseguita una rastrelliera.Combinazione di jQuery Mobile taphold e jQuery UI draggable

Draggable viene inizializzato su elementi nel seguente codice:

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

Come si può vedere la funzionalità è disabilitata trascinabile inizialmente, perché voglio per consentirle dopo un evento taphold. Per raggiungere questo obiettivo Attualmente sto usando il seguente codice:

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

Questo funziona, ma il problema è che un 'Release-e-tap-again'-evento è necessaria al fine di trascinare l'elemento attorno, invece di trascinamento direttamente dopo l'evento taphold. Potrebbe trattarsi di una sorta di problema di interferenza degli eventi? Ho provato cose come event.preventDefault() ma la mia conoscenza degli eventi di jQuery non è molta quindi non ho idea se questo dovrebbe fare o meno alcuna differenza.

Qualche idea su come risolvere questo?

+0

Il codice funziona perfettamente con jQuery Mobile 1.4.4 e versioni successive, non è necessario il trucco suggerito di seguito. –

risposta

1

Innanzitutto, jquery ui draggable non funziona con gli eventi di tocco. Suppongo che tu abbia fatto gli aggiustamenti necessari per risolvere questo problema.

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

Avanti Direi che l'evento touchstart non sta scorrendo grazie a come taphold è stato implementato in jquery mobile.

Il trascinamento può essere avviato solo se viene attivato un evento touchstart/mousedown.

Ho visto qualcosa di simile prima, ma con un doubletap in combinazione con un trascinabile.

Potrebbe essere necessario attivare manualmente l'evento TouchStart all'interno del vostro gestore di eventi taphold per il draggable a calciare 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); 
}); 
+0

Con jQuery UI Touch Punch [collegamento] (http://touchpunch.furf.com/) trascina e rilascia con jQuery – martinoss

+0

@martinoss scusa ma questo non funziona su iOS. Vedi http://stackoverflow.com/q/36013627/582727 – Daniel

1

Anche se un po 'in ritardo - ho avuto questo lavoro saltando il plugin taphold e l'utilizzo di questo anziché. Ricorda di aggiungere 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); 
});