可拖动+可排序和可滚动的 div

Posted

技术标签:

【中文标题】可拖动+可排序和可滚动的 div【英文标题】:Draggable+Sortable & Scrollable Divs 【发布时间】:2010-11-04 05:34:19 【问题描述】:

我有一个包含可拖动项目列表的容器和一个包含可排序项目列表的容器。可拖动对象和可排序列表是连接的,允许用户将可拖动对象的克隆拖动到已排序列表中。

可拖动项目出现在垂直列表中,但可排序项目出现在水平列表中,通过将它们向左浮动来实现。可排序项目的容器将其溢出设置为自动,如果内容溢出,则会产生水平滚动条。两个容器紧挨着出现,左侧是可拖动的,右侧是可排序的。

我遇到的问题是,当可排序项的容器向右滚动时,从可拖动项的容器中拖动会立即触发可排序项的事件。看起来好像 sortables 容器的内容被移动到 draggables 容器后面。

这是我的代码:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" dir="ltr">
<head>
    <title>Sortables in scrollable divs</title>
    <script type="text/javascript" language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
    <script type="text/javascript" language="JavaScript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.1/jquery-ui.min.js"></script>
    <script type="text/javascript" language="javascript">
        $(function() 
            $("#sortable").sortable(
                start: function(event, ui) 
                    if (ui.helper !== null) console.log("sortable \"" + ui.helper.text() + "\" drag start");
                ,
                stop: function(event, ui) 
                    if (ui.helper !== null) console.log("sortable \"" + ui.helper.text() + "\" drag stopped");
                    if (ui.item !== null) console.log("sortable item \"" + ui.item.text() + "\" drag stopped");
                
            );

            $("#sortable").sortable("disable");

            $("#draggable li").draggable(
                connectToSortable: '#sortable',
                helper: 'clone',
                revert: 'invalid',
                cursor: "default",
                cursorAt:  top: -5, left: -5 ,
                start: function(event, ui) 
                    if (ui.helper !== null) console.log("draggable \"" + ui.helper.text() + "\" drag start");
                ,
                stop: function(event, ui) 
                    if (ui.helper !== null) console.log("draggable \"" + ui.helper.text() + "\" drag stopped");
                
            );

            $("#container2").mouseenter(function() 
                console.log("enter sortable container");
                $("#sortable").sortable("enable");
            ).mouseleave(function() 
                console.log("leaving sortable container");
                $("#sortable").sortable("disable");
            );

            $("#draggable, #sortable").disableSelection();
        );
    </script>
    <style type="text/css">
        html, body, p, td, th, li, input, select, option, textarea
        
            font-family: Verdana, Arial, Helvetica, sans-serif;
            font-size: 11px;
            color:#343E41;
        

        .wrapper
        
            position: relative;
            width: 100%;
            height: 100%;
            overflow: hidden;
            height: expression(this.parentNode.offsetHeight + "px");
        

        .scroll-wrapper
        
            position: relative;
            width: 100%;
            height: 100%;
            overflow: auto;
            height: expression(this.parentNode.offsetHeight + "px");
        

        #container1
        
            float:left;
            width:200px;
            height:400px;
            overflow:auto;
            border:solid #000 1px;
            margin:5px;
        

        #container2
        
            float:left;
            width:600px;
            height:400px;
            overflow:auto;
            border:solid #000 1px;
            margin:5px;
        

        ul#draggable
        
            padding:0;
            margin:0;
            list-style-image:none;
            list-style-position:outside;
            list-style-type:none;
        

        ul#draggable li
        
            display:block;
            margin:5px;
            border:solid #000 1px;
            height:50px;
            width:150px;
        

        ul#sortable
        
            padding:0;
            margin:0;
            list-style-image:none;
            list-style-position:outside;
            list-style-type:none;
            height:380px;
            width:744px;
        

        ul#sortable li
        
            display:block;
            float:left;
            margin:5px;
            border:solid #000 1px;
            height:370px;
            width:50px;
            text-align:center;
        
    </style>
</head>
<body>
    <form id="form1" action="">
        <div id="container1">
            <ul id="draggable">
                <li>1A</li>
                <li>2A</li>
                <li>3A</li>
                <li>4A</li>
                <li>5A</li>
                <li>6A</li>
                <li>7A</li>
                <li>8A</li>
                <li>9A</li>
                <li>10A</li>
                <li>11A</li>
                <li>12A</li>
            </ul>
        </div>
        <div id="container2">
            <ul id="sortable">
                <li class="ui-state-default">1</li>
                <li class="ui-state-default">2</li>
                <li class="ui-state-default">3</li>
                <li class="ui-state-default">4</li>
                <li class="ui-state-default">5</li>
                <li class="ui-state-default">6</li>
                <li class="ui-state-default">7</li>
                <li class="ui-state-default">8</li>
                <li class="ui-state-default">9</li>
                <li class="ui-state-default">10</li>
                <li class="ui-state-default">11</li>
                <li class="ui-state-default">12</li>
            </ul>
        </div>
    </form>
</body>

如何避免在项目被拖到可排序容器上之前触发可排序事件?

提前致谢

【问题讨论】:

【参考方案1】:

自从我发布这个问题以来已经有很长时间了,从那时起,jQuery 和 jQuery UI 的新版本已经发布。

另外,jQuery UI 的开发团队增加了一个与 sortables 连接的 Draggables 的例子,被添加了。

所以我更新了上面的原始示例代码并对其进行了修改,使其与我的场景相匹配。我想要一个水平滚动的可排序部分,它会在添加新项目时自动展开。

下面的示例解决了我的问题,代码看起来更简洁:

$(function () 
            $("#sortable").sortable(
                revert: true,
                start: function (event, ui) 
                    $(this).width($(this).width() + ui.helper.width() + 12);
                ,
                stop: function (event, ui) 
                    var w = 0;
                    $(this).children("li").each(function () 
                        w += $(this).width() + parseInt($(this).css("margin-left")) + parseInt($(this).css("margin-right")) + 2;
                    );
                    $(this).width(w);
                
            );

            var w = 0;
            $("#sortable").children("li").each(function () 
                w += $(this).width() + parseInt($(this).css("margin-left")) + parseInt($(this).css("margin-right")) + 2;
            );
            $("#sortable").width(w);

            $("#draggable li").draggable(
                connectToSortable: "#sortable",
                helper: "clone",
                revert: "invalid"
            );
            $("ul, li").disableSelection();
        );
html, body, p, td, th, li, input, select, option, textarea
                
                        font-family: Verdana, Arial, Helvetica, sans-serif;
                        font-size: 11px;
                        color:#343E41;
                

                .wrapper
                
                        position: relative;
                        width: 100%;
                        height: 100%;
                        overflow: hidden;
                        height: expression(this.parentNode.offsetHeight + "px");
                

                .scroll-wrapper
                
                        position: relative;
                        width: 100%;
                        height: 100%;
                        overflow: auto;
                        height: expression(this.parentNode.offsetHeight + "px");
                

                #container1
                
                        float:left;
                        width:200px;
                        height:400px;
                        overflow:auto;
                        border:solid #000 1px;
                        margin:5px;
                

                #container2
                
                        float:left;
                        width:600px;
                        height:400px;
                        overflow:auto;
                        border:solid #000 1px;
                        margin:5px;
                

                ul#draggable
                
                        padding:0;
                        margin:0;
                        list-style-image:none;
                        list-style-position:outside;
                        list-style-type:none;
                

                ul#draggable li
                
                        display:block;
                        margin:5px;
                        border:solid #000 1px;
                        height:50px;
                        width:150px;
                

                ul#sortable
                
                        padding:0;
                        margin:0;
                        list-style-image:none;
                        list-style-position:outside;
                        list-style-type:none;
                        height:380px;
                

                ul#sortable li
                
                        display:block;
                        float:left;
                        margin:5px;
                        border:solid #000 1px;
                        height:370px;
                        width:50px;
                        text-align:center;
                
           <script type="text/javascript" language="JavaScript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script>
        <script type="text/javascript" language="JavaScript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
 
    <form id="form1" action="">
    <div id="container1">
    <ul id="draggable">
    <li>1A</li>
    <li>2A</li>
    <li>3A</li>
    <li>4A</li>
    <li>5A</li>
    <li>6A</li>
    <li>7A</li>
    <li>8A</li>
    <li>9A</li>
    <li>10A</li>
    <li>11A</li>
    <li>12A</li>
    </ul>
    </div>
    <div id="container2">
    <ul id="sortable">
    <li class="ui-state-default">1</li>
    <li class="ui-state-default">2</li>
    <li class="ui-state-default">3</li>
    <li class="ui-state-default">4</li>
    <li class="ui-state-default">5</li>
    <li class="ui-state-default">6</li>
    <li class="ui-state-default">7</li>
    <li class="ui-state-default">8</li>
    <li class="ui-state-default">9</li>
    <li class="ui-state-default">10</li>
    <li class="ui-state-default">11</li>
    <li class="ui-state-default">12</li>
    </ul>
    </div>
    </form>

认为某个地方的某个人可能也想做同样的事情并需要一些帮助:D

【讨论】:

我把你的代码放在一个 jsfiddle 上,所以在运行中尝试很方便 :) here it is

以上是关于可拖动+可排序和可滚动的 div的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 可拖放和可滚动的 div

jQuery 可拖动和可拖放,在可拖动 ul 上滚动

使用jQuery可拖动将项目拖动到可滚动的div之外

jQuery ui 可拖动元素在滚动 div 之外不能“拖动”

基于可拖动元素滚动 div

jQuery - 窗口滚动后的可拖动位置问题