【问题标题】:Dynamically created elements not draggable动态创建的元素不可拖动
【发布时间】:2019-06-14 09:48:11
【问题描述】:

我有一个简单的块,它的元素是动态添加到 DOM 中的,我希望用户能够创建一个块,并且它应该可以使用 jsplumb 库拖动。

不幸的是,现在我可以创建元素但它们不可拖动,但如果我手动将它们添加到 dom,它是可拖动的。

这是我目前所拥有的

function addMovieButton() {

    var newMovieBlockButton = $("<div class='movie-button w'>Button New<div class='ep' action='begin'></div><div>");

}

这里是 plumb.js

jsPlumb.ready(function () {

    // setup some defaults for jsPlumb.
    var instance = jsPlumb.getInstance({
        Endpoint: ["Dot", {radius: 5}],
        Connector:"StateMachine",
        HoverPaintStyle: {stroke: "#1e8151", strokeWidth: 2 },
        ConnectionOverlays: [
            [ "Arrow", {
                location: 1,
                id: "arrow",
                length: 14,
                foldback: 0.8
            } ],
            [ "Label", { label: "FOO", id: "label", cssClass: "aLabel" }]
        ],
        Container: "canvas"
    });

    instance.registerConnectionType("basic", { anchor:"Continuous", connector:"StateMachine" });

    window.jsp = instance;

    var canvas = document.getElementById("canvas");
    var windows = jsPlumb.getSelector(".statemachine-demo .w");
    var windows_movie = jsPlumb.getSelector(".statemachine-demo .movie-block ");

    // bind a click listener to each connection; the connection is deleted. you could of course
    // just do this: jsPlumb.bind("click", jsPlumb.detach), but I wanted to make it clear what was
    // happening.
    instance.bind("click", function (c) {
        instance.deleteConnection(c);
    });

    // bind a connection listener. note that the parameter passed to this function contains more than
    // just the new connection - see the documentation for a full list of what is included in 'info'.
    // this listener sets the connection's internal
    // id as the label overlay's text.
    instance.bind("connection", function (info) {
        info.connection.getOverlay("label").setLabel(info.connection.id);
    });

    // bind a double click listener to "canvas"; add new node when this occurs.
    jsPlumb.on(canvas, "dblclick", function(e) {
      //  newNode(e.offsetX, e.offsetY);
    });

    //
    // initialise element as connection targets and source.
    //
    var initNode = function(el) {

        // initialise draggable elements.
        instance.draggable(el);

        instance.makeSource(el, {
            filter: ".ep",
            anchor: "Continuous",
            connectorStyle: { stroke: "#5c96bc", strokeWidth: 2, outlineStroke: "transparent", outlineWidth: 4 },
            connectionType:"basic",
            extract:{
                "action":"the-action"
            },
            maxConnections: 6,
            onMaxConnections: function (info, e) {
                alert("Maximum connections (" + info.maxConnections + ") reached");
            }
        });

        instance.makeTarget(el, {
            dropOptions: { hoverClass: "dragHover" },
            anchor: "Continuous",
            allowLoopback: true
        });

        // this is not part of the core demo functionality; it is a means for the Toolkit edition's wrapped
        // version of this demo to find out about new nodes being added.
        //
        instance.fire("jsPlumbDemoNodeAdded", el);
    };

    // suspend drawing and initialise.
    instance.batch(function () {
        for (var i = 0; i < windows.length; i++) {
            initNode(windows[i], true);
            console.log(windows[i]);
        }
        for (var j = 0; j < windows_movie.length; j++) {
            initNode(windows_movie[j], true);
            console.log(windows_movie[j]);
        }


    });

    jsPlumb.fire("jsPlumbDemoLoaded", instance);

});

这里是现场演示live demo

这里是笨蛋full source code

在上面的演示中,只需右键添加电影块进行测试

为什么可拖动对动态创建的元素不起作用?

【问题讨论】:

  • 在将新元素添加到 DOM 后,您需要再次调用 initNode(),以便在它们上初始化 draggable()
  • 简单的答案是事件监听器不能应用于初始化库函数时不存在的元素
  • @RoryMcCrossan 我需要在哪里调用 initNode()??
  • 在你追加新内容之后
  • 您从中调用函数的位置不在jsPlumb.ready() 处理程序的范围内

标签: javascript jquery html jsplumb


【解决方案1】:

这里是一个示例page,当我第一次发现“jsplumb”时,它完全可以满足您的需求,因此您可能想要使用它或在它之上构建。
请记住,确实应该在将元素添加到 DOM 后调用 draggable 方法,我的示例非常简单:

  • 它不需要jsplumb.fire
  • 它不需要.ready 绑定
  • 它不需要 jsplumb 提供的“批处理”处理

这样你就可以避免像准备好的范围和其他我仍在努力掌握的问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多