【问题标题】:why does cytoscape nodes need two taps instead of one to fire click event为什么 cytoscape 节点需要两次点击而不是一次才能触发点击事件
【发布时间】:2019-01-02 11:26:17
【问题描述】:

我正在使用 cytoscape.js 构建网络视图,并且需要捕获节点上的点击事件。该事件在边缘和背景上触发得很好,但需要两次点击才能在节点上触发。我使用了如下所示的“点击”和“点击”事件,但仍然无法在第一次点击时触发该事件。任何线索!?

cy.on('tap',function(e){
  // console.log(e)
  console.log('click detected ', e)
})

谢谢

【问题讨论】:

    标签: javascript jquery vue.js cytoscape.js


    【解决方案1】:

    你总是需要在绑定之前取消绑定事件,否则你可能会遇到一些事件触发 twiche 的问题。

    此外,您应该指定要将事件绑定到哪些元素,因此可以选择“节点”、“边缘”或其他所有元素。这样你的事件就更准确了。

    var cy = (window.cy = cytoscape({
      container: document.getElementById("cy"),
    
      boxSelectionEnabled: false,
      autounselectify: true,
    
      style: [{
          selector: "node",
          css: {
            content: "data(id)",
            "text-valign": "center",
            "text-halign": "center",
            height: "60px",
            width: "60px",
            "border-color": "black",
            "border-opacity": "1",
            "border-width": "10px"
          }
        },
        {
          selector: "$node > node",
          css: {
            "padding-top": "10px",
            "padding-left": "10px",
            "padding-bottom": "10px",
            "padding-right": "10px",
            "text-valign": "top",
            "text-halign": "center",
            "background-color": "#bbb"
          }
        },
        {
          selector: "edge",
          css: {
            "target-arrow-shape": "triangle"
          }
        },
        {
          selector: "edge[label]",
          css: {
            label: "data(label)",
            "text-rotation": "autorotate",
            "text-margin-x": "0px",
            "text-margin-y": "0px"
          }
        },
        {
          selector: ":selected",
          css: {
            "background-color": "black",
            "line-color": "black",
            "target-arrow-color": "black",
            "source-arrow-color": "black"
          }
        }
      ],
      layout: {
        name: "circle"
      }
    }));
    
    var info = [{
        name: "Peter",
        next_op_name: "Claire"
      },
      {
        name: "Claire",
        next_op_name: "Mike"
      },
      {
        name: "Mike",
        next_op_name: "Rosa"
      },
      {
        name: "Rosa",
        next_op_name: "Peter"
      }
    ];
    
    cy.ready(function() {
      var array = [];
      // iterate over info once
      for (var i = 0; i < info.length; i++) {
        array.push({
          group: "nodes",
          data: {
            id: info[i].name, // id is name!!!
            label: info[i].name
          }
        });
        array.push({
          group: "edges",
          data: {
            id: "e" + i,
            source: info[i].name,
            target: info[i].next_op_name,
            label: "e" + i
          }
        });
      }
      cy.add(array);
      cy.layout({
        name: "circle"
      }).run();
    });
    
    // Here is the important part
    cy.unbind("tap"); // unbind event to prevent possible mishaps with firing too many events
    cy.bind("tap", function(evt) { // bind with .bind() (synonym to .on() but more intuitive
      console.log(evt.target);
    });
    body {
      font: 14px helvetica neue, helvetica, arial, sans-serif;
    }
    
    #cy {
      height: 100%;
      width: 75%;
      position: absolute;
      left: 0;
      top: 0;
      float: left;
    }
    <html>
    
    <head>
      <meta charset=utf-8 />
      <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
      <script src="https://unpkg.com/cytoscape@3.3.0/dist/cytoscape.min.js"></script>
      <!-- qtip imports -->
      <script src="https://unpkg.com/jquery@3.3.1/dist/jquery.js"></script>
      <script src="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.js"></script>
      <link href="http://cdnjs.cloudflare.com/ajax/libs/qtip2/2.2.0/jquery.qtip.min.css" rel="stylesheet" type="text/css" />
      <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-qtip/2.7.0/cytoscape-qtip.js"></script>
    
      <!-- dagre imports -->
      <script src="https://unpkg.com/dagre@0.7.4/dist/dagre.js"></script>
      <script src="https://cdn.rawgit.com/cytoscape/cytoscape.js-dagre/1.5.0/cytoscape-dagre.js"></script>
    </head>
    
    <body>
      <div id="cy"></div>
    </body>
    
    </html>

    【讨论】:

    • 非常感谢!但是仍然需要单击两次才能在节点上触发点击事件。我认为这是由于 cytoscape 的内部工作。第一次点击触发edgehandler的启动功能,允许绘制边缘。
    • 不,代码对我来说一键运行,你确定你的文件中有 cytoscape 和代码的所有部分(取消绑定等)吗?
    • 我将 cytoscape 与 vue.js 一起使用。我用 npm 导入了 cytoscape,我想一切都在那里。我在mounted里面写了tap函数并试图做bind unbind,但没有改变任何东西!!
    • 你能提供一个可重现的例子(通过 sn-p),否则它就是大海捞针:D
    • 事件冒泡,就像在 DOM 中一样。在点击节点时,处理程序会为节点调用一次,并为核心调用一次。使用像@StephanT 这样的选择器。建议,或将侦听器直接添加到特定节点。
    猜你喜欢
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    • 1970-01-01
    相关资源
    最近更新 更多