【问题标题】:D3 events - How to allow button click in d3 element?D3 事件 - 如何允许在 d3 元素中单击按钮?
【发布时间】:2013-10-26 18:13:36
【问题描述】:

我有一个美国所有县的 SVG 渲染图。每条路径都绑定了四个事件:

click : opens up tooltip graphic with three buttons
dblclick : executes zoom effect
mouseover : shows tooltip with county/state data, changes fill
mouseout : returns fill to original

我的问题是我想区分打开带有按钮的工具提示的地图的点击事件和该工具提示内的按钮。

我通过

创建工具提示
thisObj._tooltip = d3.select("body")
  .append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

地图是通过

创建的
d3.json("/static/js/json/us-counties.json", function(json){

  thisObj._svg.selectAll("path")
    .data(json.features)
    .enter().append("path")
    .attr("d", thisObj._path)
    .attr("class", "states")
    .attr("id", function(d){
      return d.id;
    })
    .style("fill", "gray")
    .style("stroke", "black")
    .style("stroke-width", "0.5px")
    .on("click", mapClick)
    .on("dblclick", mapZoom)
    .on("mouseover", mapMouseOver)
    .on("mouseout", mapMouseOut);
});

我的 mapClick 处理程序是

var mapClick = function(d, i){

    if (thisObj._tooltipOpen){

        if ($(".button").is(":checked")){

            console.log($(this).attr("id") + " was clicked");

        } else {

            console.log("Close tooltip click recorded");
            thisObj._tooltip.transition()
                .duration(500)
                .style("opacity", 0);

            thisObj._tooltipOpen = false;

            mapMouseOut(d);
        }

    } else {
        console.log("Open tooltip click recorded");

        //tooltip template in html, want to handle a button click on these buttons
        var template = "<div id = 'tooltip_template'>" + 
            "<div class = 'county_data'>" + d.name + ", " + d.properties.StateCode + "</div>" +
            "<button id = 'add_prospective_market' class = 'button'>Prospective Market</button>" +
            "<button id = 'add_market' class = 'button'>Market County</button>" +
            "<button id = 'remove_market' class = 'button'>Remove Market</button></div>";

        thisObj._tooltip.html(template)
            .style("left", (d3.event.pageX) + "px")
            .style("top", (d3.event.pageY + "px"));

        $(".button").button();

        thisObj._tooltip.transition()
            .duration(1000)
            .style("opacity", .8);

        thisObj._tooltipOpen = true;
    }
}

我有一个通过实例化的按钮处理程序

$("#add_market").on("click", function(){
   console.log("Add Market button clicked");
}

但它从未被激活,我得到的唯一日志是工具提示打开/关闭通知。鉴于此代码,如何修改单击处理程序以区分按钮单击和非按钮单击?

【问题讨论】:

  • 您是否会忽略工具提示 div 中的指针事件?
  • @LarsKotthoff,这是您和 reblace 建议的结合。我更改了指针事件设置并将按钮事件绑定到每个单击事件的工具提示。

标签: javascript jquery svg d3.js


【解决方案1】:

我猜你在做

$("#add_market").on("click", function(){
   console.log("Add Market button clicked");
}

处理程序在该 id 存在之前注册,因此处理程序没有注册到任何东西。由于这是一个 jQuery 选择,如果它为空,您将不会收到错误,如果 ID 为“add_market”的元素尚不存在,则会发生这种情况。

尝试在注册处理程序的代码块之前/之后放置一个日志语句:

console.log("About to register the listener");
$("#add_market").on("click", function(){
   console.log("Add Market button clicked");
}
console.log("Done registering the listener");

并查看它是否在“打开工具提示单击记录”日志消息之前/之后。或者,您可以在这一行设置断点:

$("#add_market").on("click", function(){

并查看“$("#add_market")” jQuery 选择是否找到任何内容。

要修复它,您可以在模板本身中注册监听器,也可以在创建工具提示和按钮后粘贴监听器注册代码。

【讨论】:

  • 您对事件注册不具有约束力的看法很好。我现在在工具提示的实例化上绑定按钮事件侦听器。
【解决方案2】:

如果父元素具有值为“none”的css属性“pointer-events”,那么它将阻止子元素的鼠标和触摸事件,解决方案是添加相同的属性(“pointer-events”)子元素的值为“auto”,则子元素将触发事件。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-30
    • 1970-01-01
    • 2017-09-06
    • 2016-02-14
    • 2021-08-11
    • 1970-01-01
    相关资源
    最近更新 更多