代码之家  ›  专栏  ›  技术社区  ›  jasongetsdown

jquery可拖放范围问题

  •  3
  • jasongetsdown  · 技术社区  · 16 年前

    参见代码 here on jsbin. 我基本上是在尝试创建一系列开关。每个填满的红色方块都可以上下拖动。底部的红色轮廓线是放置区域。当一个正方形拖过一个有资格接受它的放置区域时,放置区域应该变成粉红色。

    此代码有两个问题。其一是,虽然切换的运动被限制在Y轴上,但它们仍然可以在任何放置区域上放置。单击并拖动一个切换按钮,在最下面一行滑动,您会看到放置区域变为粉红色,即使切换按钮保持不变。

    这导致了第二个问题。为了解决这个问题,我尝试使用scope选项,它对drags和drops进行分组。拖动只能放置在具有相同作用域的放置区域上。在上面的示例中,添加作用域的行被注释掉。每次拖放的范围是“默认”。

    如果取消对这两行的注释(如果您是新加入JSBIN的,请单击右上角的选项卡,然后在更改后单击预览),您将看到,它们不再可以放置在一个放置区域中,而不是将每个拖动限制在一个放置区域中。 任何 落区回调函数从不激发。

    为了方便起见,下面是示例的javascript部分:

    $(document).ready( function() {
        var draggables = $('div.dragMe'),
        droppables = $('div.dropMe');
    
        draggables.draggable(
        {
            axis: 'y',
            containment: 'parent'
        });
    
        droppables.droppable(
        {
            hoverClass: 'dropped',
            drop: dropCallBack
        });
    
        draggables.each(function(index) {
            //$(this).draggable('option', 'scope', ''+index);
            //droppables.eq(index).droppable('option', 'scope', ''+index);
    
            $(this).text( $(this).draggable('option', 'scope') )
            droppables.eq(index).text( droppables.eq(index).droppable('option', 'scope') );
        });
    
        function dropCallBack(e, ui) {
            alert('Dropped!');
        }
    });
    
    1 回复  |  直到 16 年前
        1
  •  9
  •   Simen Echholt    16 年前

    jquery在设置 scope 通过选项函数可下拉的选项。jquery维护一个包含所有已注册的可排序文件的数组(我们称之为 S 现在),其中每个键都是一个特定的范围。当您将可拖动元素放入Droppable中时,jquery将检查可拖动元素的作用域属性,并检查您尝试拖动的可拖动元素是否存在于 S[scope] . 如果不是的话,这意味着你想要放入的可拖放的范围与可拖动的范围不同。

    问题是,当您通过执行 .droppable('option', 'scope', ...) 数组 S 没有更新。其他所有内容(据我所见)都已正确更新(实际jquery对象的选项属性等),从而在通过 .droppable('option', 'scope') .

    我发现其他几个人也有同样的问题,没有解决方案,当我搜索解决方案时,这个问题就出现了。( "jquery droppable scope option" ,所以我认为在解决问题之前提供一个临时的解决方案是有用的。我做了一个扩展函数,在可能与其他选项发生冲突方面测试得不是很好,但至少这是一个开始。 $.ui.ddmanager.droppables 是我调用的数组吗 S 以前。

    jQuery.fn.extend({
    
        setDroppableScope: function(scope) {
            return this.each(function() {
                var currentScope = $(this).droppable("option","scope");
                if (typeof currentScope == "object" && currentScope[0] == this) return true; //continue if this is not droppable
    
                //Remove from current scope and add to new scope
                var i, droppableArrayObject;
                for(i = 0; i < $.ui.ddmanager.droppables[currentScope].length; i++) {
                    var ui_element = $.ui.ddmanager.droppables[currentScope][i].element[0];
    
                    if (this == ui_element) {
                        //Remove from old scope position in jQuery's internal array
                        droppableArrayObject = $.ui.ddmanager.droppables[currentScope].splice(i,1)[0];
                        //Add to new scope
                        $.ui.ddmanager.droppables[scope] = $.ui.ddmanager.droppables[scope] || [];
                        $.ui.ddmanager.droppables[scope].push(droppableArrayObject);
                        //Update the original way via jQuery
                        $(this).droppable("option","scope",scope);
                        break;
                    }
                }
            });
        }
    });
    

    您的示例如下

    draggables.each(function(index) {
        $(this).draggable('option', 'scope', ''+index);
        droppables.eq(index).setDroppableScope(''+index);
    
        $(this).text( $(this).draggable('option', 'scope') )
        droppables.eq(index).text( droppables.eq(index).droppable('option', 'scope') );
    });
    

    Here's the updated jsbin