Javascript Kéo và thả cho các thiết bị cảm ứng [đã đóng]


120

Tôi đang tìm kiếm một plugin kéo & DROP hoạt động trên các thiết bị cảm ứng.

Tôi muốn có chức năng tương tự như plugin jQuery UI cho phép các phần tử "có thể thả xuống".

Các jqtouch Plugin hỗ trợ kéo, nhưng không giảm.

Đây là tính năng kéo và thả chỉ hỗ trợ iPhone / iPad.

Có ai có thể chỉ cho tôi hướng plugin kéo và thả hoạt động trên android / ios không?

... Hoặc có thể cập nhật plugin jqtouch để có thể tải xuống, nó đã chạy trên Andriod và IOS.

Cảm ơn!


1
Quá trình này đang được tiến hành, nhưng tôi không biết thiết bị nào hỗ trợ nó: This plugins.jquery.com/project/mobiledraganddrop ... bạn đã xem qua các thư viện jQuerymobile.com chưa? Tôi cũng tìm thấy câu hỏi SO trùng lặp này: stackoverflow.com/questions/3172100/…
iivel

Cảm ơn. Yeah mobiledraganddrop chỉ hỗ trợ nhấp và thả trên thiết bị di động. Tôi không thể tìm thấy bất kỳ thứ gì trên jQuerymobile.com. Câu hỏi khác có câu trả lời đã được đánh dấu là đúng, đề cập đến sencha.com/products/touch có giấy phép nguồn hạn chế.
joe

Tôi tò mò về một ứng dụng hoạt động trên các trình duyệt dành cho thiết bị di động và máy tính để bàn.
Lime

Câu trả lời:


258

Bạn có thể sử dụng giao diện người dùng Jquery để kéo và thả với một thư viện bổ sung giúp chuyển các sự kiện chuột thành cảm ứng, đó là những gì bạn cần, thư viện tôi đề xuất là https://github.com/furf/jquery-ui-touch-punch , với điều này kéo và thả của bạn từ giao diện người dùng Jquery sẽ hoạt động trên các phát minh cảm ứng

hoặc bạn có thể sử dụng mã này mà tôi đang sử dụng, nó cũng chuyển đổi các sự kiện chuột thành cảm ứng và nó hoạt động như ma thuật.

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

Và trong tài liệu của bạn, chỉ cần gọi hàm init ()

mã được tìm thấy từ đây


11
Cảm ơn, trên thiết bị Android của tôi, nội dung hiện có thể kéo được. Tuy nhiên, sự kiện nhấp chuột không được kích hoạt nữa khi tôi nhấp vào nó. Bất kỳ ý tưởng làm thế nào để sửa chữa điều đó?
John Landheer

9
Lưu ý: Vì trình nghe sự kiện được đăng ký cho toàn bộ tài liệu, giải pháp này cũng vô hiệu hóa tính năng cuộn trên Nexus S của tôi ...
Ethan Leroy

29
Cảm ơn vì đã chia sẻ điều này. Tuy nhiên, bạn nên ghi công cho tác giả gốc của mã bạn đã đăng. ross.posterous.com/2008/08/19/iphone-touch-events-in-javascript
undefined

2
@JohnLandheer Tôi đã khắc phục sự cố bằng cách chỉ gắn trình nghe sự kiện với các đối tượng mà tôi muốn có thể kéo được,document.getElementById('draggableContainer').addEventListener(...
ớtNUT

1
Touch-punch là tuyệt vời. Một trong những thứ 'nó chỉ hoạt động'. Than ôi, nó không hỗ trợ cảm ứng kép ... mà tôi rất muốn xem.
ĐA.

21

Đối với bất kỳ ai muốn sử dụng tính năng này và giữ chức năng 'nhấp chuột' (như John Landheer đã đề cập trong nhận xét của mình), bạn có thể thực hiện chỉ với một vài sửa đổi:

Thêm một vài hình cầu:

var clickms = 100;
var lastTouchDown = -1;

Sau đó, sửa đổi câu lệnh switch từ bản gốc thành sau:

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

Bạn có thể muốn điều chỉnh 'clickms' theo sở thích của mình. Về cơ bản, nó chỉ theo dõi một 'touchstart' nhanh chóng theo sau là một 'touchhend' để mô phỏng một cú nhấp chuột.


@EZ Hart - bạn có thể vui lòng cho tôi biết nơi đặt mã của bạn ở trên mã đã cho để kích hoạt sự kiện nhấp chuột không ???
Valay

1
@ChakoDesai - Mã trong câu trả lời đã được chỉnh sửa rất nhiều kể từ khi tôi viết câu trả lời của mình. Kiểm tra stackoverflow.com/posts/6362527/revisions và xem mã từ ngày 30 tháng 6 năm 2011; câu trả lời của tôi sẽ có ý nghĩa hơn dựa trên phiên bản đó.
EZ Hart

@EZ Hart - Tôi đã cập nhật mã của mình từ url đã cho. Nhưng tại sao đôi khi clickhoạt động và đôi khi không ???
Valay

@ChakoDesai - Không nhìn thấy mã của bạn, tôi không thể chắc chắn. Bạn có thể muốn mở một câu hỏi mới cho điều đó.
EZ Hart

Bạn có thể tìm thấy câu trả lời cập nhật để làm cho mã trên hoạt động với các sự kiện nhấp chuột tại đây: stackoverflow.com/questions/28218888/…
Blunderfest

12

Cảm ơn các mã trên! - Tôi đã thử một số lựa chọn và đây là vé. Tôi đã gặp sự cố trong đó PreventDefault ngăn không cho cuộn trên ipad - tôi hiện đang thử nghiệm các mục có thể kéo và nó hoạt động tốt cho đến nay.

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

Bạn đã thử nghiệm điều này trong Windows Phone chưa? Hay bất cứ thứ gì khác ngoài iPhone? Theo kinh nghiệm trước đây, điều này dường như hoạt động hoàn hảo trên iPhone / iPad, nhưng không hoạt động tốt trên các thiết bị khác, đặc biệt là trong Windows Phone.
gần như là người mới bắt đầu vào

10

Tôi đã có giải pháp tương tự như câu trả lời gregpress , nhưng các mục có thể kéo của tôi sử dụng một lớp thay vì một id. Nó dường như hoạt động.

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

4
Việc bạn chỉ đơn giản sử dụng một bộ chọn khác không đảm bảo là một câu trả lời riêng biệt, nhưng thay vào đó, bạn nên nhận xét về câu trả lời của @ gregpress.
bPratik

2
@bPratik trừ khi anh ta muốn định dạng đẹp hơn mà câu trả lời cung cấp - và việc anh ta cung cấp toàn bộ ví dụ về mã đảm bảo một câu trả lời riêng biệt. Nên đã để lại một bình luận liên kết đến câu trả lời của anh ấy mặc dù ...
drzaus

8

Chủ đề cũ tôi biết .......

Vấn đề với câu trả lời của @ryuutatsuo là nó cũng chặn bất kỳ đầu vào hoặc phần tử nào khác phải phản ứng khi 'nhấp chuột' (ví dụ: đầu vào), vì vậy tôi đã viết giải pháp này. Giải pháp này giúp bạn có thể sử dụng bất kỳ thư viện kéo và thả hiện có nào dựa trên các sự kiện mousedown, mousemove và mouseup trên bất kỳ thiết bị cảm ứng nào (hoặc cumputer). Đây cũng là một giải pháp trình duyệt chéo.

Tôi đã thử nghiệm trên một số thiết bị và nó hoạt động nhanh (kết hợp với tính năng kéo và thả của ThreeDubMedia (xem thêm tại http://threedubmedia.com/code/event/drag )). Nó là một giải pháp jQuery nên bạn chỉ có thể sử dụng nó với jQuery libs. Tôi đã sử dụng jQuery 1.5.1 cho nó vì một số chức năng mới hơn không hoạt động đúng với IE9 trở lên (không được thử nghiệm với các phiên bản jQuery mới hơn).

Trước khi bạn thêm bất kỳ thao tác kéo hoặc thả nào vào một sự kiện, bạn phải gọi hàm này trước :

simulateTouchEvents(<object>);

Bạn cũng có thể chặn tất cả các thành phần / con cho đầu vào hoặc để tăng tốc độ xử lý sự kiện bằng cách sử dụng cú pháp sau:

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

Đây là mã tôi đã viết. Tôi đã sử dụng một số thủ thuật hay để tăng tốc độ đánh giá mọi thứ (xem mã).

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

Chức năng của nó: Lúc đầu, nó chuyển các sự kiện chạm đơn lẻ thành các sự kiện chuột. Nó kiểm tra xem một sự kiện có được gây ra bởi một phần tử trên / trong phần tử phải được kéo xung quanh hay không. Nếu nó là một phần tử đầu vào như input, textarea, v.v., nó sẽ bỏ qua bản dịch hoặc nếu một sự kiện chuột tiêu chuẩn được gắn vào nó, nó cũng sẽ bỏ qua bản dịch.

Kết quả: Mọi phần tử trên phần tử có thể kéo vẫn hoạt động.

Chúc bạn viết mã vui vẻ, helloz, Erwin Haantjes


đối tượng nào tôi nên chuyển vào simulateTouchEvents(<object>, true);???
Valay

Ví dụ: simulateTouchEvents ($ ('# yourid;), true); hoặc simulateTouchEvents (document.getElementById ('yourid'), true); vv
Codebeat

bạn có thể vui lòng nhìn vào liên kết câu hỏi khác của tôi không ???
Valay

Sử dụng threedubmedia.com/code/event/drag và tắt x hoặc y di chuyển của phần tử. Khi bạn sử dụng mã trong bài viết này, bạn có thể 'cuộn' các thanh cuộn. Nhưng không biết tại sao bạn muốn làm điều này vì một trang trên điện thoại di động đã có thanh cuộn. Không hiểu bạn muốn làm gì với nó. Sự thành công!
Codebeat

Tôi phải thêm kéo-n-thả các cột và cuộn cả hai. Khi tôi bật touchsự kiện trong chrome, tôi không thể cuộn bảng. Ngay cả trên điện thoại di động cũng không.
Valay
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.