Как я могу сделать div jQuery UI 'draggable ()' перетаскиваемым для сенсорного экрана?

112

У меня есть пользовательский интерфейс jQuery, draggable()который работает в Firefox и Chrome. Концепция пользовательского интерфейса заключается в том, чтобы щелкнуть мышью, чтобы создать элемент типа «стикер».

Обычно я нажимаю или нажимаю на div#everything(100% в высоту и ширину), который прослушивает щелчки, и отображается текстовое поле ввода. Вы добавляете текст, а когда закончите, он его сохраняет. Вы можете перетащить этот элемент. Это работает в обычных браузерах, но на iPad, с которым я могу тестировать, я не могу перетаскивать элементы. Если я касаюсь, чтобы выбрать (затем он немного тускнеет), я не могу перетащить его. Он вообще не тянется влево или вправо. Я могу перетаскивать вверх или вниз, но я перетаскиваю не отдельного человека div, а целую веб-страницу.

Итак, вот код, который я использую для захвата кликов:

$('#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);
});

А вот код, который я использую для «сохранения» заметки и превращения входного div в просто отображаемый div:

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

И у меня есть этот код, когда я загружаю страницу для сохраненных заметок:

$('.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();
    }
});

Мой STATEобъект обрабатывает сохранение заметок.

При загрузке это все тело 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>

Итак, мой вопрос: как я могу улучшить эту работу на iPad?

Я не настроен на jQuery UI, мне интересно, что я делаю неправильно с jQuery UI или jQuery, или могут быть лучшие фреймворки для создания кроссплатформенных / обратно совместимых элементов draggable (), которые будут работают для пользовательских интерфейсов с сенсорным экраном.

Также приветствуются более общие комментарии о том, как писать такие компоненты пользовательского интерфейса.

Спасибо!


ОБНОВЛЕНИЕ: мне удалось просто draggable()привязать это к моему вызову пользовательского интерфейса jQuery и получить правильную перетаскиваемость на iPad!

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

Плагин JQuery сенсорный сделал трюк!

Artlung
источник
1
Мне вот что интересно: можно ли перетащить div двумя или тремя пальцами? Я знаю, что вам иногда приходится использовать несколько пальцев для прокрутки встроенного контента в мобильном Safari, так что это может быть то же самое для «перетаскиваемого» контента.
Walter Mundt,
Вальтер Мундт, спасибо! Никаких вариаций пальцев не пробовал, попробую, когда попадет в руки!
artlung
1
два или три пальца фактически предотвратили непреднамеренную прокрутку «всей страницы», но не внесли никаких изменений в перетаскиваемую область.
artlung
К сожалению, этот метод у меня не сработал. :(
Blaster
@blaster Вам нужно будет посмотреть некоторые другие ответы на другие возможные решения
artlung

Ответы:

138

Потратив много часов, я наткнулся на это!

JQuery-UI-сенсорный удар

Он переводит события касания как события щелчка. Не забудьте загрузить скрипт после jquery.

У меня это работает на iPad и iPhone

$('#movable').draggable({containment: "parent"});
ctrl-alt-dileep
источник
2
Это решение отлично работает, еще один ответ, который я устал, был ошибочным и действительно не помог
musefan
Небольшой совет: отлично работает, хотя если перетаскиваемый элемент покрыт слоями, как изображение с маской над ним, перетаскивание не активируется, но решением будет добавление указателей-событий: none; на верхних слоях.
Адлер
Это отличное и простое решение, вы просто используете плагин и продолжаете работать с функцией перетаскивания JQuery. Отлично, спасибо!
почти новичок
Это предотвратит использование интерактивных элементов в перетаскиваемом элементе.
Абдул Садик Ялчин
61

Внимание: этот ответ был написан в 2010 году, и технологии развиваются быстро. Более новое решение см. В ответе @ ctrl-alt-dileep ниже .


В зависимости от ваших потребностей вы можете попробовать плагин jQuery touch ; вы можете попробовать пример здесь . Он отлично работает, перетаскивая на мой iPhone, тогда как jQuery UI Draggable - нет.

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

В качестве примечания: вы не поверите, но мы слышим все больше шума о том, как сенсорные устройства, такие как iPad и iPhone, вызывают проблемы как для веб-сайтов, использующих функции: hover / onmouseover, так и перетаскиваемого контента.

Если вас интересует базовое решение для этого, используйте три новых события JavaScript; ontouchstart, ontouchmove и ontouchend. Apple действительно написала статью об их использовании, которую вы можете найти здесь . Упрощенный пример можно найти здесь . Эти события используются в обоих плагинах, с которыми я связался.

vonconrad
источник
2
Супер классный! Все, что мне нужно было сделать, это подключиться .touch({ animate: false, sticky: false, dragx: true, dragy: true, rotate: false, resort: true, scale: false });к моему существующему draggable()вызову, и это работает! Мне все еще нужно проработать все события, с которыми я хочу иметь дело, чтобы наладить рабочий процесс, но плагин jQuery touch сделал свое дело!
artlung
4
плагин больше не доступен на jquery.com. вы все еще можете найти здесь javascript manifestinteractive.com/iphone/touch/js/jquery.touch.js
bjelli
1
Хех, теперь плагин отсутствует и на manifestinteractive.com. Попробуйте это: plugins.jquery.com/files/jquery.touch.js.txt
Ян Хантер,
5
этот ответ больше не действителен. см. ответ @ ctrl-alt-dileep ниже (jquery-ui-touch-punch) для ответа 2012 года
bjelli
1
@bjelli Спасибо, что указали на это. Я обновил свой ответ предупреждением. :)
vonconrad
24

Этот проект должен быть полезным - сопоставляет события касания с событиями щелчка таким образом, чтобы пользовательский интерфейс jQuery работал на iPad и iPhone без каких-либо изменений. Просто добавьте JS в любой существующий проект.

http://code.google.com/p/jquery-ui-for-ipad-and-iphone/

Стив
источник
7

jQuery ui 1.9 позаботится об этом за вас. Вот демонстрация pre:

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

Просто возьмите jquery.mouse.ui.js, вставьте его под загружаемый файл jQuery ui, и это все, что вам нужно сделать! Также работает для сортировки.

Этот код отлично работает для меня, но если вы получаете ошибки, обновленную версию jquery.mouse.ui.js можно найти здесь:

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

thatmiddleway
источник
3
Это здорово, что они имеют дело с этой 1.9. FWIW, я обнаружил, что версия кода в этой демонстрации содержала ошибки и работала не так хорошо. Кто-то опубликовал более правильную версию по этому вопросу: stackoverflow.com/questions/6745098/…, которая работает лучше для меня.
asgeo1
Я обновил свой ответ, чтобы решить эту проблему. У меня пока нет ошибок в моем варианте использования с оригиналом.
thatmiddleway
1
Ссылка Dropbox не работает.
BerggreenDK
2

Вчера я боролся с подобной проблемой. У меня уже было «рабочее» решение с использованием jQuery UI, перетаскиваемого вместе с jQuery Touch Punch, которые упоминаются в других ответах. Однако использование этого метода вызывало у меня странные ошибки в некоторых устройствах Android, поэтому я решил написать небольшой плагин jQuery, который может сделать HTML-элементы перетаскиваемыми с помощью событий касания вместо использования метода, имитирующего поддельные события мыши.

Результатом этого является jQuery Draggable Touch, который представляет собой простой плагин jQuery для создания перетаскиваемых элементов, который имеет сенсорные устройства в качестве основной цели с помощью событий касания (таких как touchstart, touchmove, touchend и т. Д.). У него все еще есть резервный вариант, который использует события мыши, если браузер / устройство не поддерживает события касания.

Heyman
источник
Привет, Хейман, отличная работа. Спасибо, что поделились этим. Будет ли это работать и для jQuery с изменяемым размером?
Харис
1

Вы можете попробовать использовать jquery.pep.js :

jquery.pep.js - это легкий плагин jQuery, который превращает любой элемент DOM в перетаскиваемый объект. Он работает практически во всех браузерах, от старого до нового, от прикосновения к щелчку. Я построил его, чтобы удовлетворить потребность, в которой перетаскиваемый интерфейс jQuery UI не выполнялся, поскольку он не работал на сенсорных устройствах (без некоторого взлома).

Веб-сайт , ссылка GitHub

Мартинас
источник
1
Спасибо @martynas, посмотрю!
artlung