2009-10-15 39 views
10

Tôi tự hỏi nếu có một cách để làm cho jQuery kéo chỉ để kéo thẳng lên, xuống và trái, phải. Tôi muốn ngăn người dùng kéo một div theo đường chéo. Không thể sử dụng tùy chọn lưới trong giao diện người dùng có thể kéo trong trường hợp của tôi.Làm thế nào để jQuery có thể kéo được với trục X và Y cố định?

http://jqueryui.com/demos/draggable/#constrain-movement

Làm thế nào có thể như vậy?

Cảm ơn!

+0

nếu bạn có thể kéo đối tượng sang trái và sang phải, lên và xuống ... bạn có thể kéo nó theo đường chéo không? hoặc bạn đang nói về từ "vị trí bắt đầu" chỉ? IE, nếu bạn bắt đầu tại 0,0 và bạn di chuyển đến một điểm vượt quá 0, -3 ... đột nhiên bạn đang bị ràng buộc theo chiều dọc chỉ? – snicker

+0

Vâng, đó là chính xác những gì tôi muốn đạt được. –

+0

Vâng, tôi đã viết mã để làm điều đó đúng, và JQuery chỉ sẽ không cho phép bạn thay đổi trục trong khi nó đang được kéo. – snicker

Trả lời

8

Tôi đã viết một plugin cho phép di chuyển một vật thể có thể kéo được ở cả hai trục. Nó được thực hiện công việc nhưng nó sẽ được thực hiện tốt hơn như là một jQuery UI widget hơn là một plugin jQuery đơn giản.

Hosted Demo: http://jsbin.com/ugadu/1 (Editable qua http://jsbin.com/ugadu/1/edit)

đang Plugin:

$.fn.draggableXY = function(options) { 
    var defaultOptions = { 
    distance: 5, 
    dynamic: false 
    }; 
    options = $.extend(defaultOptions, options); 

    this.draggable({ 
    distance: options.distance, 
    start: function (event, ui) { 
     ui.helper.data('draggableXY.originalPosition', ui.position || {top: 0, left: 0}); 
     ui.helper.data('draggableXY.newDrag', true); 
    }, 
    drag: function (event, ui) { 
     var originalPosition = ui.helper.data('draggableXY.originalPosition'); 
     var deltaX = Math.abs(originalPosition.left - ui.position.left); 
     var deltaY = Math.abs(originalPosition.top - ui.position.top); 

     var newDrag = options.dynamic || ui.helper.data('draggableXY.newDrag'); 
     ui.helper.data('draggableXY.newDrag', false); 

     var xMax = newDrag ? Math.max(deltaX, deltaY) === deltaX : ui.helper.data('draggableXY.xMax'); 
     ui.helper.data('draggableXY.xMax', xMax); 

     var newPosition = ui.position; 
     if(xMax) { 
     newPosition.top = originalPosition.top; 
     } 
     if(!xMax){ 
     newPosition.left = originalPosition.left; 
     } 

     return newPosition; 
    } 
    }); 
}; 
+0

Điều này có vẻ thú vị nhưng liên kết của bạn không hoạt động. Không thể tìm ra lý do tại sao ... –

+0

Argh! Xin lỗi, đã có một dòng gỡ lỗi trong đó đã phá vỡ nó, trừ khi bạn đã mở Firebug. Tôi đã sửa nó và thay đổi liên kết trong câu trả lời. – brianpeiris

+2

Tôi đã thực hiện một phiên bản sửa đổi mã của bạn trong chuỗi sau để hỗ trợ kéo bằng cách nới lỏng. Đó là một đoạn mã tuyệt vời mà bạn đã viết ở đó một vài năm trước đây.http://stackoverflow.com/questions/6398854/jquery-draggable-with-ease – DarthJDG

1

Tôi không có mã chính xác cho bạn, nhưng tôi có thể chỉ cho bạn đúng hướng bằng cách giúp bạn suy nghĩ về vấn đề sâu hơn một chút.

Vì vậy, người dùng bắt đầu kéo đối tượng không bị giới hạn. Như các đối tượng di chuyển một pixel đi từ điểm khởi đầu, nếu pixel đầu tiên là tại bất kỳ trong bốn (x, y) tọa độ, nơi xy là điểm khởi đầu: (x -1, y -1), (x -1, y 1), (x +1, y -1) hoặc (x -1, y 1), vẫn chưa rõ người dùng có ý nghĩa gì, Ví dụ, tôi f đối tượng nằm ở một bên trái và bên trái, không thể biết ràng buộc có phải trên trục x hay trục y hay không.

Khi bạn di chuyển nhiều hơn một pixel, nó trở nên dễ dàng hơn. Nhưng bạn vẫn phải làm một số làm tròn trên tọa độ pixel, như trong tọa độ ở trên, abs (xoffset) == abs (yoffset), Sau đó bạn có thể kích hoạt sự kiện để áp dụng ràng buộc khi x và/hoặc y khoảng cách lớn hơn một số số nguyên nhỏ tùy ý, nói "3".

Vấn đề tiếp theo cần giải quyết là cách bắn cuối cùng của giới hạn trục bạn muốn cho phép người dùng thay đổi trục. Tôi đoán rằng bạn muốn có hiệu ứng lưới, vì vậy bạn sẽ phải đặt ngưỡng di chuyển số pixel trước khi bạn loại bỏ ràng buộc và tìm "hướng" tiếp theo mà người dùng muốn kéo.

Đây là một thử thách thú vị và trải nghiệm học tập tốt nếu bạn tìm ra cách thực hiện.

3

sử dụng sự kiện kéo để lợi thế

$('.selector').draggable({ 
    drag: function(event, ui) { ... } 
}); 

của bạn tôi không chắc chắn 100% như thế nào, nhưng bên đây, bạn có thể làm một kiểm tra về các tọa độ. như ~ jack-laplante nói, đây là nơi bạn sẽ so sánh. nếu tọa độ gần trục x hơn y, hãy thay đổi trục thành x

//setter 
$('.selector').draggable('option', 'axis', 'x'); 

nếu cách khác thay đổi nó thành y. điều này sẽ giúp bạn có được một chuyển động snapping để luôn luôn có mục hoặc trên trục x hoặc trục y (từ điểm bắt đầu). bạn phải làm một kiểm tra để rời khỏi mục bất cứ nơi nào nó được nếu trục đã nói (x + n, y + n), nhưng nó sẽ là khá ấn tượng nếu ai đó có nhiều hơn một vài điểm ảnh ở trên | x | = | y | hàng.

bạn không chỉ định nếu các trục luôn ở nơi ban đầu chúng bắt đầu hoặc nếu chúng thay đổi tùy thuộc vào nơi mục kéo được bắt đầu kéo (như khi bạn di chuyển nó một chút, hãy bỏ đi và cố kéo nó một số chi tiết). có một sự khởi đầu: và kết thúc: sự kiện cũng có thể giúp bạn với phần đó.

chính xác những gì bạn đang cố kéo mà không thể đi theo đường chéo, nhưng có thể đi sang trái, phải, lên và xuống?

+0

Cảm ơn bạn đã nhập liệu! Tôi đang tạo một thư viện hình ảnh nơi người dùng sẽ kéo một hình ảnh để di chuyển đến hình ảnh tiếp theo. Nếu người dùng kéo hình ảnh lên hoặc xuống, một văn bản thông tin nhỏ sẽ được hiển thị. –

2

Tôi đang đăng câu trả lời này sau nhiều lần không nói rằng không thể thực hiện với chỉ cuộc gọi jqueryui trên đối tượng. Dường như nó sẽ không cho phép bạn thay đổi trục kiềm chế trong khi bạn đang kéo.

Hãy chứng minh tôi sai?

+0

Điều này có thể thực hiện bằng cách sử dụng trình xử lý sự kiện kéo tùy chỉnh và cập nhật đối tượng ui.position. Xem [câu trả lời này] (http://stackoverflow.com/a/16131457/289203) để biết thêm chi tiết về phương pháp này. –

8

jQueryUI hỗ trợ hai phương pháp để kiểm soát kéo vào một ca khúc cố định.

  1. Bạn có thể sử dụng tùy chọn trục để giới hạn di chuyển kéo trên trục cụ thể . Ví dụ:

    $('.draggable_horiz').draggable({axis: "x"}); 
    

    More Info ở đây: http://api.jqueryui.com/draggable/#option-axis

  2. Bạn có thể hạn chế phong trào sử dụng một thành phần hoặc một mảng của x/y tọa độ xác định một khung giới hạn.

    $('.draggable_track').draggable({ containment: [0,0, 250, 24] }); 
    
    or to just use the parent element as a reference track: 
    
        $('.draggable_track').draggable({ containment: 'parent' }); 
    

    Thông tin thêm ở đây: http://api.jqueryui.com/draggable/#option-containment

Tôi hy vọng điều này sẽ giúp.

Các vấn đề liên quan