【问题标题】:How to invoke "click" event programmatically in d3?如何在 d3 中以编程方式调用“点击”事件?
【发布时间】:2012-01-30 11:46:49
【问题描述】:

我正在尝试这样(也在https://gist.github.com/1703994):

<!DOCTYPE html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js?1.27.2"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.time.js?1.27.2"></script>

    <script type="text/javascript" src="js-libs/jquery-1.7.js"></script>

    <style>
      <!--
      #test {
      width: 400px;
      height: 500px;
      }
      -->
    </style>
  </head>

  <body>

    <script type="text/javascript">
      $(function() {
        var w = 600,
            h = 350;

        var vis = d3.select("#test").append("svg:svg")
        .attr("width", w)
        .attr("height", h)
        .append("svg:g")
        .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")");

        var g = vis.selectAll("g")
        .data([ { x:1 , y: 2} ])
        .enter().append("svg:g");

        g.append("svg:path")
        .attr("fill", "red")
        .attr("stroke", "red")
        .attr("stroke-width", "10")
        .attr("d", "M 100 350 l 150 -300")

        g.select("path")
        .on("click", function() { console.log("Hello"); });

        // XXX: how to execute click programmaticaly?
      })
    </script>

    <div id="test"></div>
  </body>
</html>

但是没用

我想我们可以使用https://github.com/mbostock/d3/wiki/Internals#wiki-dispatch_on

但是怎么做呢?

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    不知道为什么,但 jQuery 和 d3 处理事件的方式似乎存在差异,导致 jQuery 引发的点击事件 $("#some-d3-element").click() 不分派到 d3 元素。

    解决方法:

    jQuery.fn.d3Click = function () {
      this.each(function (i, e) {
        var evt = new MouseEvent("click");
        e.dispatchEvent(evt);
      });
    };
    

    然后调用它:

    $("#some-d3-element").d3Click();
    

    【讨论】:

    • 我收到此错误:超出最大调用堆栈大小。如何解决这个问题?
    • 很好,但你能帮我吗?我现在想右键单击((你能改进你的答案吗?谢谢。
    【解决方案2】:

    只需调用.on 方法作为注册值(即您的处理函数)的getter,然后调用其结果:

    g.select("path").on("click")();
    

    如果您的处理程序使用绑定的数据和/或事件字段,或者如果您绑定了多个事件侦听器(例如“click.thing1”和“click.thing2”),它会变得更加复杂。在这种情况下,您最好使用standard DOM methods 触发一个假事件:

    var e = document.createEvent('UIEvents');
    e.initUIEvent('click', true, true, /* ... */);
    g.select("path").node().dispatchEvent(e);
    

    【讨论】:

    • 对于使用@natevw 解决方案的后者的任何人,我使用window, 1 填写了剩余的值。整个通话看起来像:e.initUIEvent("click", true, true, window, 1);
    • 使用第一种方法,你会得到错误的“this” - 请参阅 Andrew Plank 的答案以获得修复。
    【解决方案3】:

    使用 D3 v4,您可能会想要这样:

    d3.select('#some-id').dispatch('click');
    

    参考:https://github.com/d3/d3-selection#selection_dispatch

    【讨论】:

    • 这是截至 09/2020 的最佳答案
    • 如果您需要根据某些条件从一组元素中选择一个元素,您可以将 select 链接到 selectAll 上,如下所示:d3.selectAll('.some-class').select(function(d){ if (condition === true) { return this } }).dispatch('click');
    【解决方案4】:

    这行得通。我正在使用饼图,因此我选择了所有“选定”饼图,并为每个饼图检索附加的“点击”回调(我已使用 d3's 附加在此处未包含的另一部分代码中。 on() 方法),然后在正确的上下文中使用预期的参数进行调用。

    d3.selectAll("g.selected").each(function(d, i) {
        var onClickFunc = d3.select(this).on("click");
        onClickFunc.apply(this, [d, i]);
    });                
    

    【讨论】:

      【解决方案5】:

      这个答案可能有点不相关——但希望对搜索如何调用 SVG 元素的点击事件的人有用——因为 jQuery $(mySvgElement).trigger("click") 不起作用。

      这是您以编程方式触发/调用/引发 SVG 元素的点击事件的方式:

      var ev = document.createEvent("SVGEvents");
      ev.initEvent("click",true,true);
      
      var target = $("svg>g>path[fill='#0011cc']").get(0); // get the SVG element here
      target.dispatchEvent(ev);  // like $(target).trigger('click') - but working!
      

      【讨论】:

        【解决方案6】:

        我来这个线程寻找 d3 mousemove 事件以进行角度单元测试。

        @natevw 回答

        g.select("path").on("click")();
        

        对鼠标悬停事件有很大帮助。但是,将其应用于 mousemove 会产生 e.source null 错误。

        解决方法是以编程方式设置 d3 事件。

        d3.event = document.createEvent('MouseEvent');
        d3.event.initMouseEvent("mousemove");
        d3.select(elm[0]).select("rect").on("mousemove")();
        

        希望这会有所帮助。

        【讨论】:

          【解决方案7】:

          您可以通过获取鼠标事件并将 d3 否则为您提供的参数传递给它来实现超级手动。这为您提供了一种相当干净的方法,同时仍然使用 d3 构造。对于单个元素,请使用以下内容:

          var path = g.select('path');
          path.on('click').call(path.node(), path.datum());
          

          对于多个元素,可以依次触发:

          g.selectAll('path').each(function(d, i) {
            d3.select(this).on('click').apply(this, arguments);
          });
          

          如果您的选择器足够具体,或者如果您使用.select() 而不是.selectAll() 仅返回第一个元素,则后者也可用于单个元素。

          【讨论】:

            【解决方案8】:

            @handler 的回答对我完全不起作用。它会单击 svg 元素,但不会注册其他模拟事件。这对我有用:

            function eventFire(el, etype){
              if (el.fireEvent) {
                el.fireEvent('on' + etype);
              } else {
                var evObj = document.createEvent('Events');
                evObj.initEvent(etype, true, false);
                el.dispatchEvent(evObj);
              }
            }
            

            用法:

            eventFire(document.getElementById(element_id), 'click');
            

            【讨论】:

              【解决方案9】:

              这就是我的做法。

              g.selectAll("path").on("click", function(d, i){
                                                  my_function(d, i);
                                              });
              

              我发现回调与匿名函数一起使用。所以对于上面的代码,任何被点击的路径都会调用my_function,并传入被点击路径的当前数据d和索引i

              【讨论】:

                【解决方案10】:

                我找到下一个解决方法:

                d3.selectAll("path").each(function(d, i) {
                                    onClickFunc.apply(this, [d, i]);
                                });
                

                d 是数据,i 是该数据的索引

                【讨论】:

                • 这并不能真正回答你的问题,它只是在d3.selectAll("path").each( onClickFunc ) 上输入更多内容。什么是 onClickFunc?
                • 这没有任何作用。应该接受 natevw 或 handler 的回答。
                • 缺少重要的代码行作为回调的第一行:var onClickFunc = d3.select(this).on("click");
                【解决方案11】:

                试试g.select("path").trigger("click")

                【讨论】:

                • 没有帮助,d3 不包含triggerprop
                • 对不起,还以为是 jQuery,看起来像……但是我建议您使用此代码。它可以在没有任何框架的情况下工作,但我只在 Firefox 下使用它... 'var section = document.getElementById("section"); if (section) { var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("点击", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); section.dispatchEvent(evt); }'
                猜你喜欢
                • 2012-03-18
                • 1970-01-01
                • 2010-10-04
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-01-22
                • 2016-06-12
                相关资源
                最近更新 更多