Set more than one containment in jQuery Draggable

前端 未结 2 660
小鲜肉
小鲜肉 2021-01-24 11:55

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.

相关标签:
2条回答
  • 2021-01-24 12:29

    set the ui containment options like following:

    containment:'selector_1, selector_2,...'
    
    0 讨论(0)
  • 2021-01-24 12:32

    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!

    0 讨论(0)
提交回复
热议问题