1

我相信我的代码中出现了循环关闭问题。我读过这篇文章 ,这对我很有帮助。最近我想出了一个类似于文章中引用的“使用闭包循环”部分的问题。我已经尝试过他们的解决方案,但仍然没有解决我的问题。我一直在到处寻找解决方案,但我总是在文章中找到解决方案。

我正在使用 jqueryui 使一些 lis 可拖动,当我将它们放入容器中时,我需要使用特定于该 li 的变量(节点)。问题是节点(和索引)总是最后一个(因此是闭包问题)。

这是我的代码(我已经简化了一点,以便更容易识别问题):

function makeDraggable(node, i) {
        $("#rightTab li#" + node.id).draggable({
            containment: 'div#container',
            stack: 'div#container',
            scroll: false,
            revert: 'invalid',
            helper: function() {
                return $(this).children().clone();
            },
            start: function(event, ui) {
                $(this).children().css('opacity', 0);
            },
            stop: function(event, ui) {
                $(this).children().css('opacity', 1);
            }
        });

        $("#vis").droppable({
            drop: test(node, i)
        });
    }

    function test(noder, index) {
        return function(event, ui) {
            alert(index);
            //stuff with node.
        }
    }

    function appendInfo(nodes) {
        for(var i = 0; i < nodes.length; i++) {
            $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>");

            if(visualization.hasImageLabel) {
                interfaceHandler.handleImageLabel(nodes[i]);
            }
            if(visualization.hasTextLabel) {
                interfaceHandler.handleTextLabel(nodes[i]);
            }

            makeDraggable(nodes[i], i);
        }
    }

当我提醒索引(在函数测试中)它总是打印 9(最大数组长度)时,节点也总是最后一个。

(抱歉英语不好)

4

2 回答 2

1

问题是它$("#vis").droppable(...)替换了任何先前定义的可放置功能,因此不能用闭包解决。

如果知道索引很重要,那么尝试使用 让每个可拖动节点知道自己的索引.data(...),并且只调用$("#vis").droppable(...)一次 in appendInfo(),而不是 in makeDraggable()

function appendInfo(nodes) {
    for(var i = 0; i < nodes.length; i++) {
        $("#rightTab #content ul").append("<li id=" + nodes[i].id + "><div></div></li>");
        if(visualization.hasImageLabel) {
            interfaceHandler.handleImageLabel(nodes[i]);
        }
        if(visualization.hasTextLabel) {
            interfaceHandler.handleTextLabel(nodes[i]);
        }
        makeDraggable(nodes[i], i);
        $(node).data('index', i); //<<< node is now aware of its own index
    }
    $("#vis").droppable({
        drop: function(event, ui) {
            alert(ui.draggable.data('index'));//I think???
            //stuff with node.
        }
    });
}

如果不需要知道索引,那么您可以直接访问可拖动的 as ui.draggable,而无需设置或获取.data()

于 2013-01-11T02:54:45.800 回答
1

You're calling $("#vis").droppable({...}) on every iteration through the loop. This sets up 10 drop event handlers; only the last one is ever fired, which was passed (node_nine, 9) as its parameters.

Check the value of ui.draggable inside your callback; it will tell you what the dropped element is.

于 2013-01-11T02:41:29.217 回答