Set more than one containment in jQuery Draggable

2019-03-01 11:09发布

I'm creating a management application with some element on the page. Those element can be dragged around. but in the page you have 2 seperate places where it could be dragged.

So is there a way you can set more then one class in the containment option of the jQuery draggeble?

Thanks

2条回答
虎瘦雄心在
2楼-- · 2019-03-01 11:45

set the ui containment options like following:

containment:'selector_1, selector_2,...'
查看更多
The star\"
3楼-- · 2019-03-01 12:09

Per containment:

Multiple types supported:

Selector: The draggable element will be contained to the bounding box of the first element found by the selector. If no element is found, no containment will be set.

Element: The draggable element will be contained to the bounding box of this element.

String: Possible values: "parent", "document", "window".

Array: An array defining a bounding box in the form [ x1, y1, x2, y2 ].

Via https://api.jqueryui.com/draggable/#option-containment - @Vaindil mentioned this


The following is a "creative" answer regarding 'multiple containment selectors' not being directly supported by jQuery UI sortable. This is an "idea" which may help; in practice it did for my app:

You could set containment using Selector or Element (see above) mode with a higher-level parent element; meaning not just the actual 'parent' but maybe something a few DOM elements higher. (If you're using sortable, you can connect the two.) Then use the draggable method over to determine if you're on a dropzone.

You can also instantiate droppable on each dropzone. Here's some code that can help you determine what element you're over --- whereas this is highlighting all dropzone targets with a light-yellow bg class ('highlight') and the specific dropzone hovered with a bright-yellow bg class ('current-target'). Maybe you can use something like this to show the user where they're allowed to drop.

function droppable_on_deactivate_out() {
    $('.dropzone').removeClass('target');
    this.$dragElm.removeClass('over-outermost-parent');
    this.$sortableElm.sortable('option', {
        connectWith: this.activateConnectWith,
        axis: 'y',
        tolerance: 'pointer'
    });
    $(this).off('mousemove.droppableNamespace mouseout.droppableNamespace');  // Cleanup listeners
    self.showGrid.tbody.animate({scrollTop: this.scrollBackTo}, 250);
}

$('.draggable').draggable({
    // Or you could instantiate `sortable` instead of this `draggable` fn
});

$('#outermost-parent').droppable({
    accept: '.draggable',
    activate: function (droppableActivateEvent, ui) {
        this.$dragElm = $(ui.draggable.context);
        this.activateConnectWith = this.$dragElm.sortable('option', 'connectWith');
    },
    deactivate: droppable_on_deactivate_out,
    over: function () {
        $(this).on('mousemove.droppableNamespace', function (mousemoveEvent) {
            $(mousemoveEvent.target)
                .addClass('current-target')
                .on('mouseout.droppableNamespace', function () {
                    $(this)
                        .removeClass('current-target')
                        .off('mousemove.droppableNamespace mouseout.droppableNamespace');  // Cleanup listeners
                });
        });
        $('.dropzone').addClass('target');
        this.$dragElm
            .addClass('over-outermost-parent');  // Indicate something on UI
            .sortable('option', {
                connectWith: '#outermost-parent',
                axis: false,
                tolerance: 'intersect'
            });
    },
    out: droppable_on_deactivate_out
});

Thus related to your containment question, depending on where the mouse/drag is (what it is over) you can alter the UI or the draggable option axis (etc) on-the-fly. Try some creative solutions like this; I hope it helps!

查看更多
登录 后发表回答