Javascript Dokunmatik cihazlar için sürükle ve bırak [kapalı]


120

Dokunmatik cihazlarda çalışan bir sürükle ve bırak eklentisi arıyorum.

"Bırakılabilir" öğelere izin veren jQuery UI eklentisine benzer işlevsellik istiyorum .

Eklenti jqtouch sürükleyerek destekler, ancak hiçbir düşüyor.

İşte sürükle & sadece iPhone / iPad desteklediğini damla.

Herkes beni android / ios üzerinde çalışan bir sürükle ve bırak eklentisi yönüne yönlendirebilir mi?

... Veya jqtouch eklentisini düşebilirlik için güncellemek mümkün olabilir, zaten Andriod ve IOS üzerinde çalışıyor.

Teşekkürler!


1
Bu devam ediyor, ancak hangi cihazların desteklediğini bilmiyorum: Bu plugins.jquery.com/project/mobiledraganddrop ... jQuerymobile.com kitaplıklarına baktınız mı? Ayrıca bu yinelenen SO sorusunu buldum: stackoverflow.com/questions/3172100/…
iivel

Teşekkürler. Evet mobiledraganddrop yalnızca mobil cihazlarda tıklama ve bırakmayı destekler. JQuerymobile.com'da hiçbir şey bulamadım. Diğer sorunun, sınırlı kaynak lisansına sahip olan sencha.com/products/touch'a atıfta bulunan ve zaten doğru olarak işaretlenmiş bir cevabı var.
joe

Mobil ve masaüstü tarayıcılarda çalışan birini merak ediyorum.
Lime

Yanıtlar:


258

Fare olaylarını dokunmaya çeviren ek bir kitaplıkla birlikte sürükle ve bırak için Jquery kullanıcı arayüzünü kullanabilirsiniz, bu da ihtiyacınız olan şeydir, önerdiğim kitaplık https://github.com/furf/jquery-ui-touch-punch , bu, Jquery kullanıcı arayüzünden sürükle ve bırak yönteminiz dokunmatik cihazlarda çalışmalıdır

ya da benim kullandığım bu kodu kullanabilirsiniz, aynı zamanda fare olaylarını dokunmaya dönüştürüyor ve sihir gibi çalışıyor.

function touchHandler(event) {
    var touch = event.changedTouches[0];

    var simulatedEvent = document.createEvent("MouseEvent");
        simulatedEvent.initMouseEvent({
        touchstart: "mousedown",
        touchmove: "mousemove",
        touchend: "mouseup"
    }[event.type], true, true, window, 1,
        touch.screenX, touch.screenY,
        touch.clientX, touch.clientY, false,
        false, false, false, 0, null);

    touch.target.dispatchEvent(simulatedEvent);
    event.preventDefault();
}

function init() {
    document.addEventListener("touchstart", touchHandler, true);
    document.addEventListener("touchmove", touchHandler, true);
    document.addEventListener("touchend", touchHandler, true);
    document.addEventListener("touchcancel", touchHandler, true);
}

Ve belgenizde zaten init () işlevini çağırın

kod adlı bulundu Burada


11
Teşekkürler, Android cihazımda artık şeyler sürüklenebilir. Ancak, tıklama olayına tıkladığımda artık tetiklenmiyor. Bunu nasıl düzelteceğine dair bir fikrin var mı?
John Landheer

9
Not: Olay dinleyicisi belgenin tamamı için kayıtlı olduğundan, bu çözüm Nexus S'mde kaydırmayı da devre dışı bırakır ...
Ethan Leroy

29
Bunu paylaştığın için teşekkürler Ancak, gönderdiğiniz kodun orijinal yazarına atıfta bulunmalısınız. ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
undefined

2
@JohnLandheer Olay dinleyicilerini yalnızca sürüklenebilir olmasını istediğim nesnelere ekleyerek sorunu document.getElementById('draggableContainer').addEventListener(...
çözdüm

1
Dokunmak harika. Şu 'sadece işe yarıyor' şeylerinden biri. Ne yazık ki, görmek istediğim ... ikili dokunuşu desteklemiyor.
DA.

21

Bunu kullanmak ve 'tıklama' işlevini korumak isteyen herkes için (John Landheer'in yorumunda bahsettiği gibi), bunu sadece birkaç değişiklikle yapabilirsiniz:

Birkaç küresel ekleyin:

var clickms = 100;
var lastTouchDown = -1;

Ardından, switch ifadesini orijinalden buna değiştirin:

var d = new Date();
switch(event.type)
{
    case "touchstart": type = "mousedown"; lastTouchDown = d.getTime(); break;
    case "touchmove": type="mousemove"; lastTouchDown = -1; break;        
    case "touchend": if(lastTouchDown > -1 && (d.getTime() - lastTouchDown) < clickms){lastTouchDown = -1; type="click"; break;} type="mouseup"; break;
    default: return;
}

'Tıklamaları' zevkinize göre ayarlamak isteyebilirsiniz. Temel olarak, bir tıklamayı simüle etmek için sadece bir 'dokunma başlangıcı' izliyor ve ardından hızlıca bir 'dokunma sonu' geliyor.


@EZ Hart - tıklama etkinliğini etkinleştirmek için kodunuzu yukarıdaki kodda nereye koyacağımı bana bildirir misiniz?
Valay

1
@ChakoDesai - Cevabımı yazdığımdan beri cevaptaki kod yoğun bir şekilde düzenlendi. Check out stackoverflow.com/posts/6362527/revisions 30 Haziran 2011 tarihinden itibaren koda ve göz; Cevabım o versiyona göre çok daha anlamlı olacaktır.
EZ Hart

@EZ Hart - Kodumu verilen url'den güncelledim. Ama neden bazen clickişe yarıyor bazen de yaramıyor ???
Valay

@ChakoDesai - Kodunuzu görmeden emin olamıyorum. Bunun için yeni bir soru açmak isteyebilirsiniz.
EZ Hart

Yukarıdaki kodun tıklama etkinlikleriyle çalışmasını sağlamak için güncellenmiş bir yanıt burada bulunabilir: stackoverflow.com/questions/28218888/…
Blunderfest

12

Yukarıdaki kodlar için teşekkürler! - Birkaç seçeneği denedim ve bu biletti. ÖnlemeDefault'un ipad'de kaydırmayı engellemesi konusunda sorunlar yaşadım - şimdi sürüklenebilir öğeleri test ediyorum ve şimdiye kadar harika çalışıyor.

if (event.target.id == 'draggable_item' ) {
    event.preventDefault();
}

Bunu Windows Phone'da test ettiniz mi? Veya iPhone dışında herhangi bir şey? Geçmiş deneyimlere göre, bu iPhone / iPad'lerde mükemmel çalışıyor gibi görünüyor, ancak diğer cihazlarda, özellikle Windows Phone'larda iyi çalışmıyor.
neredeyse başlangıç ​​seviyesi

10

Gregpress answer ile aynı çözüme sahiptim , ancak sürüklenebilir öğelerim bir id yerine bir sınıf kullanıyordu. İşe yarıyor gibi görünüyor.

var $target = $(event.target);  
if( $target.hasClass('draggable') ) {  
    event.preventDefault();  
}

4
Basitçe farklı bir seçici kullanmış olmanız, ayrı bir cevap olmayı garanti etmez, bunun yerine @ gregpress'in cevabına yorum yapmış olmalısınız.
bPratik

2
@bPratik, istemediği sürece bir cevabı biçimlendirmenin daha güzel olmasını sağlar - ve bütün bir kod örneği vermiş olması ayrı bir cevabı garanti eder. Yine de cevabına bağlantı veren bir yorum
bırakmalıydı

8

Bildiğim eski konu .......

@Ryuutatsuo'nun cevabıyla ilgili sorun, 'tıklamalara' (örneğin girdiler) tepki vermesi gereken herhangi bir girişi veya diğer öğeleri de engellemesidir, bu yüzden bu çözümü yazdım. Bu çözüm, herhangi bir dokunmatik cihaz (veya cumputer) üzerinde fare indirme, fare imleci ve fareyi kaldırma olaylarına dayanan mevcut herhangi bir sürükle ve bırak kitaplığının kullanılmasını mümkün kıldı. Bu aynı zamanda tarayıcılar arası bir çözümdür.

Ben birkaç cihaz üzerinde de test ettik ve hızlı çalışır (ThreeDubMedia sürükle ve bırak özelliği ile kombinasyon halinde (bkz http://threedubmedia.com/code/event/drag )). Bu bir jQuery çözümüdür, bu nedenle onu yalnızca jQuery kitaplıkları ile kullanabilirsiniz. Bunun için jQuery 1.5.1 kullandım çünkü bazı yeni işlevler IE9 ve üstü ile düzgün çalışmıyor (jQuery'nin yeni sürümleriyle test edilmedi).

Bir olaya herhangi bir sürükle veya bırak işlemi eklemeden önce, önce bu işlevi çağırmanız gerekir :

simulateTouchEvents(<object>);

Aşağıdaki sözdizimini kullanarak giriş için tüm bileşenleri / alt öğeleri engelleyebilir veya olay işlemeyi hızlandırabilirsiniz:

simulateTouchEvents(<object>, true); // ignore events on childs

İşte yazdığım kod. Bir şeyleri değerlendirmeyi hızlandırmak için bazı güzel numaralar kullandım (koda bakın).

function simulateTouchEvents(oo,bIgnoreChilds)
{
 if( !$(oo)[0] )
  { return false; }

 if( !window.__touchTypes )
 {
   window.__touchTypes  = {touchstart:'mousedown',touchmove:'mousemove',touchend:'mouseup'};
   window.__touchInputs = {INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,'input':1,'textarea':1,'select':1,'option':1};
 }

$(oo).bind('touchstart touchmove touchend', function(ev)
{
    var bSame = (ev.target == this);
    if( bIgnoreChilds && !bSame )
     { return; }

    var b = (!bSame && ev.target.__ajqmeclk), // Get if object is already tested or input type
        e = ev.originalEvent;
    if( b === true || !e.touches || e.touches.length > 1 || !window.__touchTypes[e.type]  )
     { return; } //allow multi-touch gestures to work

    var oEv = ( !bSame && typeof b != 'boolean')?$(ev.target).data('events'):false,
        b = (!bSame)?(ev.target.__ajqmeclk = oEv?(oEv['click'] || oEv['mousedown'] || oEv['mouseup'] || oEv['mousemove']):false ):false;

    if( b || window.__touchInputs[ev.target.tagName] )
     { return; } //allow default clicks to work (and on inputs)

    // https://developer.mozilla.org/en/DOM/event.initMouseEvent for API
    var touch = e.changedTouches[0], newEvent = document.createEvent("MouseEvent");
    newEvent.initMouseEvent(window.__touchTypes[e.type], true, true, window, 1,
            touch.screenX, touch.screenY,
            touch.clientX, touch.clientY, false,
            false, false, false, 0, null);

    touch.target.dispatchEvent(newEvent);
    e.preventDefault();
    ev.stopImmediatePropagation();
    ev.stopPropagation();
    ev.preventDefault();
});
 return true;
}; 

Ne yapar: İlk başta, tek dokunuş olaylarını fare olaylarına çevirir. Bir olayın, sürüklenmesi gereken öğenin üzerindeki / içindeki bir öğeden kaynaklanıp kaynaklanmadığını kontrol eder. Girdi, metin alanı vb. Gibi bir girdi öğesiyse çeviriyi atlar veya buna standart bir fare olayı eklenmişse çeviriyi de atlar.

Sonuç: Sürüklenebilir bir öğedeki her öğe hala çalışıyor.

Mutlu kodlama, greetz, Erwin Haantjes


hangi nesneyi simulateTouchEvents(<object>, true);geçmeliyim ???
Valay

Örneğin: simulateTouchEvents ($ ('# yourid;), true); veya simulateTouchEvents (document.getElementById ('yourid'), true); etc
Codebeat

lütfen başka bir soru bağlantıma bakar mısınız ???
Valay

Threedubmedia.com/code/event/drag kullanın ve x veya y elemanının taşınmasını devre dışı bırakın . Bu makaledeki kodu kullandığınızda, kaydırma çubuklarını 'kaydırabilirsiniz'. Ancak bunu neden yapmak istediğinizi bilin çünkü cep telefonundaki bir sayfada zaten kaydırma çubukları var. Onunla ne yapmak istediğini anlamıyorum. Başarı!
Codebeat

Sürükle-bırak sütunları eklemem ve her ikisini de kaydırmam gerekiyor. İçindeki touchetkinlikleri açtığımda chrome, tabloyu kaydıramıyorum. Cep telefonunda bile.
Valay
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.