Перетягування Javascript для сенсорних пристроїв [закрито]


120

Я шукаю плагін Drag & DROP, який працює на сенсорних пристроях.

Мені б хотілося, щоб функціонал jQuery UI використовував плагін, який дозволяє "випускати" елементи.

Jqtouch плагін підтримує перетягування, але не падаючи.

Ось перетягування, яке підтримує лише iPhone / iPad.

Чи може хтось вказати мені у бік плагіна перетягування, який працює на android / ios?

... Або можливо оновити плагін jqtouch для випадання, він вже працює на Andriod та IOS.

Дякую!


1
Це триває, але я не знаю, які пристрої підтримують це: Цей plugins.jquery.com/project/mobiledraganddrop ... Ви переглядали бібліотеки jQuerymobile.com? Я також знайшов цей дублікат SO питання: stackoverflow.com/questions/3172100 / ...
iivel

Дякую. Так, mobiledraganddrop підтримує лише натискання та падіння на мобільних пристроях. Я нічого не міг знайти на jQuerymobile.com. На інше запитання відповідь уже позначено як правильну, що стосується sencha.com/products/touch, яка має обмежену ліцензію на джерело.
Джо

Мені цікаво те, що працює в мобільних і настільних браузерах.
Лайм

Відповіді:


258

Ви можете використовувати інтерфейс Jquery для перетягування за допомогою додаткової бібліотеки, яка переводить події миші на дотик, а це те, що вам потрібно. Бібліотека, яку я рекомендую, є https://github.com/furf/jquery-ui-touch-punch , з це ваше перетягування з інтерфейсу Jquery має працювати на сенсорних пристроях

або ви можете використовувати цей код, який я використовую, він також перетворює події миші на дотик і він працює як магія.

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

А у вашому документі вже викличте функцію init ()

код, знайдений звідси


11
Дякую, на моїх пристроях Android тепер перетягується. Однак подія клацання більше не запускається, коли я натискаю на неї. Будь-які ідеї, як це виправити?
Джон Ландхер

9
Примітка: Оскільки слухач події зареєстрований у всьому документі, це рішення також вимикає прокрутку на моєму Nexus S ...
Етан Лерой

29
Дякуємо, що поділилися цим. Однак ви повинні віддати кредит оригіналу автора коду, який ви опублікували. ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
визначено

2
@JohnLandheer Я вирішив проблему, приєднавши слухачів події лише до об'єктів, які я хотів перетягнути,document.getElementById('draggableContainer').addEventListener(...
chiliNUT

1
Сенсорний удар чудовий. Один із таких речей, що "це просто працює". На жаль, він не підтримує подвійний дотик ... який я хотів би бачити.
DA.

21

Для всіх, хто хоче скористатися цим і зберегти функцію "натискання" (як згадує Джон Ландхер у своєму коментарі), ви можете це зробити лише за допомогою декількох модифікацій:

Додайте пару глобалів:

var clickms = 100;
var lastTouchDown = -1;

Потім змініть оператор переключення з початкового на це:

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;
}

Ви можете налаштувати "clickms" під свій смак. По суті, це просто спостереження за сенсорним запуском, за яким швидко рухається "дотик", щоб імітувати клацання.


@EZ Hart - чи можете ви, будь ласка, повідомити мені, куди потрібно поставити ваш код вище вказаного коду, щоб увімкнути подію натискання ???
Валай

1
@ChakoDesai - Код у відповіді сильно відредагований з моменту написання відповіді. Перевірте stackoverflow.com/posts/6362527/reitions та подивіться на код від 30 червня 2011 року; моя відповідь матиме набагато більше сенсу на основі цієї версії.
EZ Hart

@EZ Hart - я оновив свій код із вказаної URL-адреси. Але чому іноді clickпрацює, а іноді ні ???
Валай

@ChakoDesai - Без перегляду вашого коду я не можу бути впевнений. Ви можете відкрити для цього нове запитання.
EZ Hart

Оновлений відповідь , щоб вищенаведений код буде працювати з подіями клацання можна знайти тут: stackoverflow.com/questions/28218888 / ...
Blunderfest

12

Дякуємо за наведені вище коди! - Я спробував кілька варіантів, і це був квиток. У мене виникли проблеми в тому, що prevenDefault запобігав прокрутці на ipad - я зараз тестую предмет, який можна перетягувати, і він чудово працює до цих пір.

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

Ви протестували це в Windows Phone? Або що-небудь, крім iPhone? З минулого досвіду це здається, що він ідеально працює в iPhone / iPad, але не працює на інших пристроях, особливо в Windows Phone.
майже початківець

10

У мене було таке ж рішення, як відповідь gregpress , але мої елементи, що перетягуються, використовували клас замість ідентифікатора. Здається, працює.

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

4
Той факт, що ви просто використовували інший селектор, не гарантує окрему відповідь, а натомість ви повинні прокоментувати відповідь @ gregpress.
bPratik

2
@bPratik, якщо він не хотів, щоб відповідь було краще форматування - і той факт, що він подав цілий приклад коду, вимагає окремої відповіді. Потрібно залишити коментар,
посилаючись

8

Стару нитку я знаю .......

Проблема з відповіддю @ryuutatsuo полягає в тому, що він блокує також будь-який вхід чи інший елемент, який повинен реагувати на "клацання" (наприклад, на введення), тому я написав це рішення. Це рішення дозволило використовувати будь-яку існуючу бібліотеку перетягування, яка базується на подіях мусудаун, переміщення миші та миші на будь-якому сенсорному пристрої (або комп'ютері). Це також крос-браузерне рішення.

Я пройшов тестування на кількох пристроях, і він працює швидко (у поєднанні з функцією перетягування і передачі ThreeDubMedia (див. Також http://threedubmedia.com/code/event/drag )). Це рішення jQuery, тому ви можете використовувати його лише з jQuery libs. Я використовував jQuery 1.5.1 для нього, оскільки деякі новіші функції не працюють належним чином з IE9 і вище (не тестуються з новішими версіями jQuery).

Перш ніж додати будь-яку операцію перетягування або падіння до події, потрібно спочатку викликати цю функцію :

simulateTouchEvents(<object>);

Ви також можете заблокувати всі компоненти / діти для введення даних або прискорити обробку подій, використовуючи наступний синтаксис:

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

Ось код, який я написав. Я використовував кілька приємних хитрощів, щоб пришвидшити оцінку речей (див. Код).

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;
}; 

Що це робить: спочатку він переводить події одного дотику в події миші. Він перевіряє, чи подія викликана елементом в / в елементі, який необхідно перетягнути. Якщо це елемент введення, наприклад введення, textarea тощо, він пропускає переклад, або якщо до нього додається стандартна подія миші, він також пропускає переклад.

Результат: Кожен елемент перетягуваного елемента все ще працює.

Щасливе кодування, привіт, Ервін Хаантіс


який об’єкт я повинен передати simulateTouchEvents(<object>, true);???
Валай

Наприклад: simulateTouchEvents ($ ('# yourid;), true); або імітуватиTouchEvents (document.getElementById ('yourid'), true); тощо
Codebeat

Ви можете, будь ласка, подивитись на моє інше посилання на питання ???
Валай

Використовуйте threedubmedia.com/code/event/drag і вимкніть переміщення елемента x або y. Використовуючи код у цій статті, ви можете "прокручувати" смуги прокрутки. Але знайте, чому ви хочете це зробити, тому що на сторінці мобільного телефону вже є смуги прокрутки. Не розумію, що ти хочеш з цим робити. Успіху!
Codebeat

Додаю перетягування стовпців перетягування та прокручування обох. Коли я включаю touchподії chrome, я не можу прокручувати таблицю. Навіть не на мобільному.
Валай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.