-->

Droppable over event not firing on different tab

2019-08-29 12:04发布

问题:

When I try to connect 2 lists which are seperated by tabs the over event is not firing on the list on the second tab.

Here's my HTML

<div id="TabSet" class="tabs">
    <ul>
        <li class="tab"><a href="#tabs-1">Nunc tincidunt</a></li>
        <li class="tab"><a href="#tabs-2">Proin dolor</a></li>
    </ul>
    <div id="tabs-1">
        <div style="padding: 10px;">
            <ul class="list" id="list1">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <ul class="list" id="list2">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <br style="clear: both;" />
        </div>
    </div>
    <div id="tabs-2">
        <div style="padding: 10px;">
            <ul class="list" id="list3">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <ul class="list" id="list4">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <br style="clear: both;" />
        </div>
    </div>
</div>

And javascript

$(function() {
    $(".list").sortable({
        connectWith: ".list"
    }).disableSelection();

    var $tabs = $(".tabs").tabs();

    //for changing tab on over
    $(".tab").droppable({
        over: function(event, ui) {
            var $item = $(this);
            $tabs.tabs("select", $item.find("a").attr("href"));
        }
    });

    $(".list").droppable({
        over: function(event, ui) {
            var $item = $(this);
            $item.addClass('ui-state-highlight');
            console.log($item.closest('ul').attr('id'));
        },
        out: function(event, ui) {
            var $item = $(this);
            $item.removeClass('ui-state-highlight');
            ui.draggable.appendTo('#TabSet').show('slow');
        }
    });
});

I've created a working example on jsfiddle.

When you drag an item on the lists on the first tab the list gets highlighted, this is not the case on the second tab. What makes it even stranger is that when I print the id of the hovered lists, I get the id's from the first tab and not the second tab.

Any idea how to solve this?

回答1:

After fiddling with it for days and eventually asking here I found the solution to my own problem. Posting it here to help other users.

The trick is to not use droppable but use the events provided by sortable.

I did try this earlier but the helper gets lost when you switch tabs, the solution to this is to use appendto and set helper to clone. It doesn´t really get cloned but it´s an undocumented feature.

The HTML

<div id="TabSet" class="tabs">
    <ul>
        <li class="tab"><a href="#tabs-1">Nunc tincidunt</a></li>
        <li class="tab"><a href="#tabs-2">Proin dolor</a></li>
    </ul>
    <div id="tabs-1">
        <div style="padding: 10px;">
            <ul class="list" id="list1">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <ul class="list" id="list2">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <br style="clear: both;" />
        </div>
    </div>
    <div id="tabs-2">
        <div style="padding: 10px;">
            <ul class="list" id="list3">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <ul class="list" id="list4">
                <li class="ui-state-default">Item 1</li>
                <li class="ui-state-default">Item 2</li>
            </ul>
            <br style="clear: both;" />
        </div>
    </div>
</div>

And javascript

$(function() {

    $(".list").sortable({
        connectWith: ".list",
        appendTo: document.body,
        helper: 'clone',
        over: function(event, ui) {
            var $item = $(this);
            $item.addClass('ui-state-highlight');
        },
        out: function(event, ui) {
            var $item = $(this);
            $item.removeClass('ui-state-highlight');
        }
    }).disableSelection();

    //for changing tab on over
    $(".tab").droppable({
        over: function(event, ui) {
            var $item = $(this);
            $tabs.tabs("select", $item.find("a").attr("href"));
        }
    });

    var $tabs = $(".tabs").tabs();
});

The working example on jsfiddle.

EDIT Found out that my previous example didn't work with nested tabs, the solution to this is to connect the tabs to the sortable and prevent dragging of tabs and dropping on tabs.

Nested tabs working example on jsfiddle.