1

我正在测试 jQuery 的拖放功能,但在 JSconsole 中出现以下错误:

Uncaught TypeError: Cannot read property 'options' of undefined 

我正在尝试做一个棋盘游戏,你可以移动棋子,基本上是这样的:

  • 棋盘是一张桌子,空的方块是空的<td></td>
  • 非空 TD 在<div class="..."></div>里面, div 类是drag或者nodrag(取决于轮到谁)
  • 拖动时,jQuery 所做的是给出相对位置并调整顶部/左侧
  • drop的时候,我做的是获取新旧方块,并使用appendTo(),在有div的情况下,我先remove()
  • 有效放置后,我切换类dragnodrag,首先删除 droppable 属性,然后将其添加到新的 draggable

这是代码的两个关键部分(这里是 jsFidle):

function toggleDrag(){
    //remove the (old) draggables
    if($(".drag").data("draggable")){//prevent crash when nobody is draggable
        $(".drag").draggable("destroy");
    }

    //swapp classes
    var tmp=$(".drag");
    var tmp2=$(".nodrag");
    tmp.removeClass("drag").addClass("nodrag");
    tmp2.removeClass("nodrag").addClass("drag");

    //make the (new) draggables
    $(".drag").draggable({
        revert:"invalid"
    });
}

在每个正方形 ( <td>) 内:

$("td").droppable({
    drop:function(ev,ui){
        var tar=$(this);
        var xdiv=$("#"+tar.attr("id")+" div");

        //if the square is not empty
        if(xdiv.length){
            xdiv.remove();//remove piece
        }

        //I removed styles to reset Top/Left to 0
        //append_TO_ moves the div
        ui.draggable.removeAttr("style").appendTo(tar);

        //I call the toggler funcion
        toggleDrag();
    }
});

注意:我很清楚,如果你将这块棋子放在它被拖动的同一个方格中,就会发生非常糟糕的事情,在我的完整代码中,我会对可放置对象进行清理以仅允许合法移动

任何想法为什么这个完美工作的代码会触发这个控制台错误?

4

2 回答 2

1

您看到此错误是因为(显然)不允许破坏处理程序的可拖动元素。drop

解决此问题的一种hacky方法是替换

toggleDrag();

在你的drop处理程序里面

setTimeout(toggleDrag, 0);
于 2012-11-30T06:21:14.470 回答
0

经过一些测试,我得出的结论是,在droppables之后stop:触发了 draggables ,所以我只是搬到了这里:drop:toggleDrag()

$(".drag").draggable({
    //... ,
    stop:function(ev,ui){
        toggleDrag(); //a check is needed to make sure it was dropped on dropables though
    }
});

如果您将一块棋子掉到棋盘外(在棋盘缓慢返回时)并且您快速移动另一块棋子,也会触发旧问题。这也解决了这个问题。

于 2012-11-30T07:13:25.017 回答