【问题标题】:jQuery Droppables - Problems when hiding 'inactive' drop zonesjQuery Droppables - 隐藏“非活动”放置区时出现问题
【发布时间】:2011-06-02 16:00:25
【问题描述】:

我有一个相当长的 div 列表,我试图将它们用作可放置元素 - 但我想隐藏所有不接受当前可拖动元素的可放置元素。

我在 http://jsfiddle.net/N3uh3/ 上放了一个例子

基本上,如果我拖动“Drag A”元素,它将隐藏所有“Droppable B”元素并允许我拖放到正确的元素上,这很好用。

但是,如果我拖动“拖动 B”元素,它将隐藏所有“可放置 A”元素,但其余放置区域不接受我的可拖动项目。如果我将项目放置在“可放置 B”元素的原始位置,那么它会正确放置(即使元素的位置已经移动)。如果我使用“可见性:隐藏;”而不是“display:none”,这也适用于元素不移动。

我希望这是有道理的 - 似乎可放置区域设置为元素的原始位置....有什么办法解决这个问题吗?

.lhs { width: 40%; float:left; }
.rhs { width: 40%; float:right; }
.lhs div { margin: 4px; }
.a { background-color: green; }
.b { background-color: red; }
.ui-state-highlight { background-color: yellow; }
.dropZones .ui-droppable { display: none; }
.dropZones .ui-state-highlight { display: block; }
.currentDropZone { display: block; }

<div class="wrapper">
    <div class="lhs">
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="a">DROP A</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
        <div class="b">DROP B</div>
    </div>
    <div class="rhs">
        <div class="a">Drag A</div>
        <br />
        <div class="b">Drag B</div>
    </div>
</div>


$(document).ready(function(){
    $('.rhs div').draggable({
        helper: function (e,ui) {
            // this sets the clone to be a child of the body - fixing overflow:auto problems on divs!
            return $(this).clone().appendTo('body').css('zIndex',5).show();
        }, 
        revert: 'invalid',
        cursor: 'move',
        start: function(){
            //$('.lhs').addClass('dropZones');    // immediately hides so doesn't get the ui-state-highlight class'

            // give a quick period of time then add the class
            setTimeout(function() { $('.lhs').addClass('dropZones'); }, 250);
        },
        stop: function(){
            $('.lhs').removeClass('dropZones');
        },
    });

    $('.lhs div').each(function(){
        $(this).droppable({
            greedy: true,
            activeClass: 'ui-state-highlight',
            accept: '.' + $(this).attr('class'),
            drop: function(event, ui) {
                $(this).append($(ui.draggable).clone());
            },
            activate: function(){
                $(this).addClass('currentDropZone');
            },
            deactivate: function(){
                $(this).removeClass('currentDropZone');
            }

        });
    });
});

提前致谢!

【问题讨论】:

    标签: jquery css jquery-ui html jquery-ui-droppable


    【解决方案1】:

    问题是隐藏你的非活动droppables会改变元素流和活动元素的位置。当你的延迟事件触发时,绝对可放置位置已经被 jQuery UI 缓存了,这就是你放开鼠标按钮时检查的内容。在您的原始示例中,如果您将 B 拖动到位于可见列表下方的 B 放置区的旧位置,您仍然可以放置 B

    一个快速简单的解决方案是告诉 jQuery UI 使用可拖动对象上的 refreshPositions: true 选项重新计算每次鼠标移动时的可放置​​位置。来自documentation

    refreshPositions:布尔值

    如果设置为 true,则全部可丢弃 位置计算在每个 鼠标移动。注意:这可以解决问题 在高度动态的页面上,但是 显着降低性能。

    您更新了演示:http://jsfiddle.net/N3uh3/1/

    这是一个快速解决方案,但我的建议是在隐藏您的项目时制定您自己的逻辑,而不是依赖 setTimeout(),这会在隐藏您的 droppables 之前增加一个明显令人讨厌的延迟。

    由于只显示了可放置对象被激活,我会在 jQuery UI 甚至有机会建立一个接受可放置对象的列表之前添加我的隐藏逻辑,例如项目上的 mousedown 事件。然后你可以做你自己的自定义代码来隐藏不需要的droppables,所以在缓存位置时,它们是正确的,并且不需要在每次mousemove时刷新缓存,这可能是一项昂贵的操作,具体取决于你有droppables。

    【讨论】:

    • 干杯 DarthJDG。现在像魅力一样工作 - 非常感谢!
    • 对于任何感兴趣的人 - 我已经使用 Darth 的建议更新了 jsfiddle - 更好! jsfiddle.net/N3uh3
    猜你喜欢
    • 2010-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多