jQuery ui可拖动元素在滚动div外无法拖动

36

我有一个带有预设高度/宽度和CSS样式 overflow: auto 的div中有许多元素(浮动的href标签)。

这是div的结构:

<div id="tagFun_div_main">
<div id="tf_div_tagsReturn">
    <!-- all the draggable elements go in here, the parent div scolls -->
</div>
<div id=" tf_div_tagsDrop">
    <div id="tf_dropBox"></div>
</div></div>

父级div的'tf_div_tagsReturn'和'tf_div_tagsDrop'最终会相邻浮动。

这是在创建所有'class name'为'tag_cell'的'draggable'元素后运行的jQuery代码:

$(function() {
    $(".tag_cell").draggable({ 
        revert: 'invalid', 
        scroll: false,
        containment: '#tagFun_div_main'
    });
    $("#tf_dropBox").droppable({
        accept: '.tag_cell',
        hoverClass: 'tf_dropBox_hover',
        activeClass: 'tf_dropBox_active',
        drop: function(event, ui) {
            GLOBAL_ary_tf_tags.push(ui.draggable.html());
            tagFun_reload();
        }
    });
}); 

正如我之前所述,可拖动的元素只能在div 'tf_div_tagsReturn'内进行拖动,但它们不能在父div范围之外进行可视拖动。值得注意的是,如果我正在拖动其中一个可拖动元素,并将鼠标移动到id为'tf_dropBox'的可放置div上,则会触发hoverclass类,只是我看不到可拖动的元素。

这是我第一次尝试使用jQuery,希望我只是错过了一些非常明显的东西。到目前为止,我一直在阅读文档和搜索论坛,但仍未成功:(

更新:

非常感谢Jabes88提供的解决方案,它使我实现了我正在寻找的功能。这是我的jQuery代码:

$(function() {
    $(".tag_cell").draggable({ 
        revert: 'invalid', 
        scroll: false,
        containment: '#tagFun_div_main',
        helper: 'clone',
        start : function() {
        this.style.display="none";
        },
        stop: function() {
        this.style.display="";
        }
    });
    $(".tf_dropBox").droppable({
        accept: '.tag_cell',
        hoverClass: 'tf_dropBox_hover',
        activeClass: 'tf_dropBox_active',
        drop: function(event, ui) {
            GLOBAL_ary_tf_tags.push(ui.draggable.html());
            tagFun_reload();
        }
    });
}); 

这个对我有用:https://dev59.com/a0rSa4cB1Zd3GeqPXZLe - Valamas
评论:不要混用“和'。坚持使用其中之一。非常,非常重要的三个感叹号。 - Ярослав Рахматуллин
设置 helper: 'clone' 就解决了问题 - 太棒了!! - 虽然我使用了 this.style.visibility='hidden' 来隐藏原始元素,因为玩弄 display 是不好的。 - kbro
2个回答

44

你是否想允许拖动对象有多个实例?那么可以使用 helper 和 append 选项:

$(".tag_cell").draggable({ 
  helper: 'clone',
  appendTo: 'div#myHelperHolder'
});

那么在你的CSS中,你可以将div#myHelperHolder的z-index设置为999。 如果不行,尝试使用z-index选项:

然后在 CSS 中,您可以将 div#myHelperHolder 的 z-index 设置为 999。如果不行,尝试只使用 z-index 选项:

$(".tag_cell").draggable({ 
  zIndex: 999
});

我还建议设置addClasses,以防止插件添加所有那些浪费处理器速度的烦人类名。

更新:我有一个新解决方案

好吧,经过一番尝试,我想出了这个方法:滚动选项不能阻止子元素被overflow隐藏。我看了一些其他帖子,但都找不到单一的解决方案。但我想出了一个解决方法来完成任务。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <script type="text/javascript" src="http://www.google.com/jsapi"></script>
    <script type="text/javascript">
    google.load("jquery", "1.4.0");
    google.load("jqueryui", "1.7.2");   
    google.setOnLoadCallback(OnLoad);
    function OnLoad(){
        var dropped = false;
        $(".tag_cell").draggable({ 
            addClasses: false,
            revert: 'invalid',
            containment: '#tagFun_div_main',
            helper: 'clone',
            appendTo: '#tagFun_div_helper',
            start: function(event, ui) {
                dropped = false;
                $(this).addClass("hide");
            },
            stop: function(event, ui) {
                if (dropped==true) {
                    $(this).remove();
                } else {
                    $(this).removeClass("hide");
                }
            }
        });
        $("#tf_dropBox").droppable({
            accept: '.tag_cell',
            hoverClass: 'tf_dropBox_hover',
            activeClass: 'tf_dropBox_active',
            drop: function(event, ui) {
                dropped = true;
                $.ui.ddmanager.current.cancelHelperRemoval = true;
                ui.helper.appendTo(this);
            }
        });
    }
    </script>
    <style>
        div#tagFun_div_main { display:block; width:800px; height:400px; margin:auto; padding:10px; background:#F00; }
        div#tf_div_tagsReturn { display:block; width:200px; height:100%; float:left; overflow:auto; background:#000; }
        div#tf_div_tagsDrop { display:block; width:200px; height:100%; float:right; background:#0F0; }
        div#tf_dropBox { display:block; width:100%; height:250px; background:#F0F; }
        span.tag_cell { display:block; width:25px; height:25px; margin:1px; float:left; cursor:pointer; background:#0FF; z-index:99; }
        span.tag_cell.hide { display:none; }
        div#tf_dropBox.tf_dropBox_hover { background:#FFF !important; }
        div#tf_dropBox.tf_dropBox_active { background:#333; }
    </style>
</head>
<body>
    <div id="tagFun_div_main">
        <div id="tf_div_tagsReturn">
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
            <span class="tag_cell"></span>
        </div>
        <div id="tf_div_tagsDrop">
            <div id="tf_dropBox"></div>
        </div>
    </div>
    <div id="tagFun_div_helper">
    <!-- this is where the helper gets appended for temporary use -->
    </div>
</body>
</html>

我复制了我的整个代码,这样你就可以尝试一下。以下是简要描述: 当您开始拖动一个项目时,它会隐藏原始项目并克隆它,然后将克隆项目添加到溢出区域外的容器中。一旦放下,它会删除原始项目并将克隆项目移动到放置区域。很好,现在我们已经解决了溢出问题,但遇到了其他问题。当您将克隆项目拖放到放置区域时,它会消失。为了防止发生这种情况,我使用了以下方法:

$.ui.ddmanager.current.cancelHelperRemoval = true;

现在我们已经阻止了帮助程序被删除,但它仍然在 "div#tagFun_div_helper" 中,而原始的可拖动项目已经重新出现。

ui.helper.appendTo(this);

这将把位于 "div#tagFun_div_helper" 的帮助器移动到我们的拖放区域。

dropped = true;

这将告诉我们的停止函数删除组中的原始项目,而不是删除“.hide”类。希望能帮到你!


谢谢您的回复。 我没有使用helper/clone,但我将zindex设置为999,问题仍然存在。我真的不知道问题出在哪里,我开始怀疑这是否可能,但我必须想象人们经常在滚动div中包含可拖动元素。感谢您提供addClasses建议,我已经实现了它。 请分享您对此滚动问题的任何其他建议/想法。 - Seth
我已经更新了我的回复,包括一个新的解决方案。看一下吧。我还注意到你的一个div id的第一个字母前有一个空格 <div id="tf_div_tagsDrop">。我不认为这会影响任何事情,但我觉得你应该知道 :-) - Justin Bull
Jabes - 谢谢你的解决方案,我很感激你花费的时间。最终,我使用了你的方法的修改版本来实现我所需的功能。在元素被拖放后,我不需要担心它仍然显示在可放置的 div 中。关于包含可拖动元素的 div,在其中一个元素被拖放后,我会刷新它,并根据刚刚拖放的内容添加新元素。我正在更新我的原始问题,并附上我最终采用的 jQuery 代码,非常感谢你回答我的问题! - Seth
1
我很高兴能帮助Stu。如果您方便的话,我会非常感激您的点赞 :) - Justin Bull
我遇到了同样的问题,并且已经应用了类似于Justin上面解决方案的代码,但是请注意,在将元素拖入可放置区域后,它会附加style=postition:absolute和top和left坐标。然后该元素在其他地方就无法再次拖动,除非我刷新页面 - 是否有一种方法可以确保助手克隆获得与原始元素相同的属性,以便它也可以被拖动?TIA - Trevor North
如果我想在拖动时也能在溢出的 div 中滚动怎么办?这是我的完整问题。这里是我的完整问题 - poshest

21

在我的情况下,这对我解决了问题并且完美地工作!

更新

$(".amigo").draggable({
            revert: "invalid" ,
            helper: function(){
                $copy = $(this).clone();
                return $copy;},
            appendTo: 'body',
            scroll: false
        });

3
助手函数:helper: function () { $copy = $(this).clone(); $copy.css({"list-style":"none","width":$(this).outerWidth()}); return $copy; } - George
是的,这正是我所需要的。我试图将可拖动的 div 移动到 Telerik MVC 网格中滚动分页模式之外,而上面的 appendTo 和 scroll 选项解决了问题。 - anewcomer
$copy 在 JQueryUI 中有特殊含义吗?为什么不用 return $(this).clone(); - user2173353
clone() 不会复制已应用于源节点的 CSS 属性。如果您想保留像宽度和填充这样的视觉元素,您必须重新应用它们。$copy 的使用只是一个变量的命名约定,$ 通常用于指示变量引用 jQuery 对象。 - PeterToTheThird
我发现在使用单引号或双引号时会有很大的区别。appendTo: 'body'对我无效,但是appendTo: "body"却有效。同样地,helper: 'clone'什么也不做,但是helper: "clone"比你这里做得更好。 - Peril Ravine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接