Bagaimana cara membuat div jQuery UI 'draggable ()' dapat diseret untuk layar sentuh?

112

Saya memiliki UI jQuery draggable()yang berfungsi di Firefox dan Chrome. Konsep antarmuka pengguna pada dasarnya adalah klik untuk membuat item jenis "post-it".

Pada dasarnya, saya mengklik atau mengetuk div#everything(100% tinggi dan lebar) yang mendengarkan klik, dan area teks input ditampilkan. Anda menambahkan teks, dan setelah selesai teks akan menyimpannya. Anda dapat menyeret elemen ini ke sekitar. Itu berfungsi di browser normal, tetapi di iPad saya dapat menguji dengan saya tidak bisa menyeret item. Jika saya sentuh untuk memilih (lalu sedikit meredup), saya tidak dapat menyeretnya. Itu tidak akan menyeret kiri atau kanan sama sekali. Saya dapat menyeret ke atas atau ke bawah, tetapi saya tidak menyeret individu div, saya menyeret seluruh halaman web.

Jadi, inilah kode yang saya gunakan untuk menangkap klik:

$('#everything').bind('click', function(e){
    var elem = document.createElement('DIV');
    STATE.top = e.pageY;
    STATE.left = e.pageX;
    var e = $(elem).css({
        top: STATE.top,
        left: STATE.left
    }).html('<textarea></textarea>')
    .addClass('instance')
    .bind('click', function(event){
        return false;
    });
    $(this).append(e);
});

Dan inilah kode yang saya gunakan untuk "menyimpan" catatan dan mengubah div input menjadi hanya div tampilan:

$('textarea').live('mouseleave', function(){
    var val = jQuery.trim($(this).val());
    STATE.content = val;
    if (val == '') {
        $(this).parent().remove();
    } else {
        var div  = $(this).parent();
        div.text(val).css({
            height: '30px'
        });
        STATE.height = 30;
        if ( div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight ) {
            while (div.width() !== div[0].clientWidth || div.height () !== div[0].clientHeight) {
                var h = div.height() + 10;
                STATE.height = h;
                div.css({
                    height: (h) + 'px'
                });     // element just got scrollbars
            }
        }
        STATE.guid = uniqueID()
        div.addClass('savedNote').attr('id', STATE.guid).draggable({
            stop: function() {
                var offset = $(this).offset();
                STATE.guid = $(this).attr('id');
                STATE.top = offset.top;
                STATE.left = offset.left;
                STATE.content = $(this).text();
                STATE.height = $(this).height();
                STATE.save();
            }
        });
        STATE.save();
        $(this).remove();
    }
});

Dan saya memiliki kode ini ketika saya memuat halaman untuk catatan yang disimpan:

$('.savedNote').draggable({
    stop: function() {
        STATE.guid = $(this).attr('id');
        var offset = $(this).offset();
        STATE.top = offset.top;
        STATE.left = offset.left;
        STATE.content = $(this).text();
        STATE.height = $(this).height();
        STATE.save();
    }
});

STATEObjek saya menangani penyimpanan catatan.

Onload, ini seluruh isi html:

<body> 
    <div id="everything"></div> 
<div class="instance savedNote" id="iddd1b0969-c634-8876-75a9-b274ff87186b" style="top:134px;left:715px;height:30px;">Whatever dude</div> 
<div class="instance savedNote" id="id8a129f06-7d0c-3cb3-9212-0f38a8445700" style="top:131px;left:347px;height:30px;">Appointment 11:45am</div> 
<div class="instance savedNote" id="ide92e3d13-afe8-79d7-bc03-818d4c7a471f" style="top:144px;left:65px;height:80px;">What do you think of a board where you can add writing as much as possible?</div> 
<div class="instance savedNote" id="idef7fe420-4c19-cfec-36b6-272f1e9b5df5" style="top:301px;left:534px;height:30px;">This was submitted</div> 
<div class="instance savedNote" id="id93b3b56f-5e23-1bd1-ddc1-9be41f1efb44" style="top:390px;left:217px;height:30px;">Hello world from iPad.</div> 

</body>

Jadi, pertanyaan saya sebenarnya adalah: bagaimana saya bisa membuat ini berfungsi lebih baik di iPad?

Saya tidak disetel pada jQuery UI, saya bertanya-tanya apakah ini adalah sesuatu yang saya lakukan salah dengan jQuery UI, atau jQuery, atau apakah mungkin ada kerangka kerja yang lebih baik untuk melakukan elemen draggable () yang kompatibel lintas platform / mundur yang akan berfungsi untuk UI layar sentuh.

Komentar yang lebih umum tentang cara menulis komponen UI seperti ini akan diterima juga.

Terima kasih!


PEMBARUAN: Saya bisa dengan mudah draggable()menghubungkan ini ke panggilan jQuery UI saya dan mendapatkan draggability yang benar di iPad!

.touch({
    animate: false,
    sticky: false,
    dragx: true,
    dragy: true,
    rotate: false,
    resort: true,
    scale: false
});

The jQuery Sentuh Plugin melakukan trik!

artlung
sumber
1
Saya ingin tahu tentang sesuatu: dapatkah Anda menyeret div dengan dua atau tiga jari? Saya tahu bahwa Anda terkadang harus menggunakan banyak jari untuk menggulir konten yang disematkan di Safari seluler, jadi mungkin sama untuk konten yang "dapat diseret".
Walter Mundt
Terima kasih Walter Mundt! Saya belum mencoba variasi jari apa pun, saya akan mencobanya ketika saya mendapatkannya di tangan saya!
artlung
1
dua atau tiga jari sebenarnya mencegah "seluruh halaman" bergulir secara tidak sengaja, tetapi tidak membuat perubahan untuk dapat diseret.
artlung
Sayangnya, teknik ini tampaknya tidak berhasil untuk saya. :(
blaster
@blaster Anda harus melihat beberapa jawaban lain untuk solusi lain yang mungkin
artlung

Jawaban:

138

Setelah membuang banyak waktu, saya menemukan ini!

jquery-ui-touch-punch

Ini menerjemahkan peristiwa tap sebagai peristiwa klik. Ingatlah untuk memuat skrip setelah jquery.

Saya mendapatkan ini berfungsi di iPad dan iPhone

$('#movable').draggable({containment: "parent"});
ctrl-alt-dileep
sumber
2
Solusi ini berfungsi dengan baik, jawaban lain yang saya lelah adalah buggy dan benar-benar tidak membantu
musefan
Sebuah tip kecil: berfungsi dengan baik, meskipun jika elemen draggable ditutupi dengan lapisan seperti gambar dengan topeng di atasnya, tidak ada drag yang diaktifkan tetapi solusinya adalah menambahkan pointer-events: none; di lapisan atas.
Adler
Ini adalah solusi yang bagus dan sederhana, Anda cukup menggunakan plugin dan terus bekerja dengan fungsi draggable JQuery. Sempurna, terima kasih!
hampir menjadi pemula
Ini akan mencegah item yang dapat diklik dalam draggable.
Abdul Sadik Yalcin
61

Perhatian: Jawaban ini ditulis pada tahun 2010 dan teknologi bergerak cepat. Untuk solusi yang lebih baru, lihat jawaban @ ctrl-alt-dileep di bawah .


Tergantung pada kebutuhan Anda, Anda mungkin ingin mencoba plugin sentuh jQuery ; Anda dapat mencoba contohnya di sini . Ini berfungsi dengan baik untuk menyeret iPhone saya, sedangkan jQuery UI Draggable tidak.

Atau, Anda dapat mencoba plugin ini , meskipun itu mungkin mengharuskan Anda untuk benar-benar menulis fungsi draggable Anda sendiri.

Sebagai catatan samping: Percaya atau tidak, kami mendengar semakin banyak desas-desus tentang bagaimana perangkat sentuh seperti iPad dan iPhone menyebabkan masalah baik untuk situs web yang menggunakan: fungsi hover / onmouseover dan konten yang dapat diseret.

Jika Anda tertarik dengan solusi yang mendasari untuk ini, itu untuk menggunakan tiga peristiwa JavaScript baru; ontouchstart, ontouchmove, dan ontouchend. Apple sebenarnya telah menulis artikel tentang penggunaannya, yang dapat Anda temukan di sini . Contoh yang disederhanakan dapat ditemukan di sini . Peristiwa ini digunakan di kedua plugin yang saya tautkan.

vonconrad.dll
sumber
2
Sangat luar biasa! Yang harus saya lakukan hanyalah menghubungkan .touch({ animate: false, sticky: false, dragx: true, dragy: true, rotate: false, resort: true, scale: false });ke draggable()panggilan saya yang ada dan itu berhasil! Saya masih harus mengerjakan semua kejadian yang ingin saya tangani untuk mendapatkan alur kerja yang benar, tetapi plugin jQuery touch berhasil!
artlung
4
plugin tampaknya tidak tersedia lagi di jquery.com. Anda masih dapat menemukan javascript di sini manifestinteractive.com/iphone/touch/js/jquery.touch.js
bjelli
1
Heh, sekarang plugin juga hilang dari manifestinteractive.com. Coba ini: plugins.jquery.com/files/jquery.touch.js.txt
Ian Hunter
5
jawaban ini tidak lagi valid. lihat jawaban @ ctrl-alt-dileep di bawah (jquery-ui-touch-punch) untuk jawaban 2012
bjelli
1
@bjelli Terima kasih telah menunjukkan hal ini. Saya telah memperbarui jawaban saya dengan peringatan. :)
vonconrad
7

jQuery ui 1.9 akan menangani ini untuk Anda. Berikut ini demo dari pra:

https://dl.dropbox.com/u/3872624/lab/touch/index.html

Ambil saja jquery.mouse.ui.js, tempelkan di bawah file ui jQuery yang Anda muat, dan hanya itu yang harus Anda lakukan! Berfungsi untuk dapat diurutkan juga.

Kode ini berfungsi dengan baik untuk saya, tetapi jika Anda mendapatkan kesalahan, versi terbaru jquery.mouse.ui.js dapat ditemukan di sini:

Jquery-ui sortable tidak berfungsi pada perangkat sentuh berbasis Android atau IOS

jalan tengah itu
sumber
3
Ini bagus mereka berurusan dengan 1.9 ini. FWIW, saya menemukan versi kode dalam demo itu memiliki bug di dalamnya dan tidak berfungsi dengan baik. Seseorang memposting versi yang lebih benar untuk pertanyaan ini: stackoverflow.com/questions/6745098/… yang bekerja lebih baik untuk saya.
asgeo1
Saya memperbarui jawaban saya untuk mengatasi ini. Saya belum mendapatkan kesalahan dalam kasus penggunaan saya dengan yang asli.
thatmiddleway
1
Tautan Dropbox tidak aktif.
BerggreenDK
2

Saya berjuang dengan masalah serupa kemarin. Saya sudah memiliki solusi "yang berfungsi" menggunakan jQuery UI yang dapat diseret bersama dengan jQuery Touch Punch, yang disebutkan dalam jawaban lain. Namun, menggunakan metode ini menyebabkan bug aneh di beberapa perangkat Android bagi saya, dan oleh karena itu saya memutuskan untuk menulis plugin jQuery kecil yang dapat membuat elemen HTML dapat diseret dengan menggunakan peristiwa sentuh daripada menggunakan metode yang meniru peristiwa mouse palsu.

Hasil dari ini adalah jQuery Draggable Touch yang merupakan plugin jQuery sederhana untuk membuat elemen draggable, yang memiliki perangkat sentuh sebagai target utamanya dengan menggunakan event sentuh (seperti touchstart, touchmove, touchend, dll.). Masih memiliki fallback yang menggunakan peristiwa mouse jika browser / perangkat tidak mendukung peristiwa sentuh.

Hei bro
sumber
Hai Heyman, Kerja bagus. Terima kasih telah membagikannya. Apakah ini akan berfungsi untuk jQuery yang dapat diubah ukurannya juga?
Haris
1

Anda dapat mencoba menggunakan jquery.pep.js :

jquery.pep.js adalah plugin jQuery ringan yang mengubah setiap elemen DOM menjadi objek yang dapat diseret. Ia bekerja di hampir semua browser, dari lama ke baru, dari sentuhan hingga klik. Saya membangunnya untuk melayani kebutuhan di mana draggable jQuery UI tidak terpenuhi, karena itu tidak berfungsi pada perangkat sentuh (tanpa beberapa peretasan).

Situs web , tautan GitHub

martynas
sumber
1
Terima kasih @martynas, saya akan memeriksanya!
artlung