单击带有D3.js的元素后,防止鼠标移动操作

时间:2016-07-23 12:47:56

标签: javascript d3.js svg onclick mouseout

我想在用户单击此元素时阻止元素的mouseout操作。有关示例,请参阅此JSFiddle(即使我点击标签,圆圈也会消失)。

有没有一种简单的方法来实现d3.js的目标?谢谢!

JSFiddle示例代码:

var svg = d3.select("#content")
                        .append("svg")
            .attr("width", 600)
            .attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
                            .text("Click me")
              .style("fill", "Blue")
              .attr("x", 50)
              .attr("y", 50)
              .on("mouseover", mouseover)
              .on("mouseout", mouseout)
              .on("click", click);

var circle = g.append("circle")
                                .style("fill", "Orange")
                .attr("cx", 150)
                .attr("cy", 90)
                .attr("r", 15)
                .classed("hide", true)
                .classed("someClass", true);

function mouseover(p){
    d3.selectAll("circle.someClass").classed("hide", false);
}
function mouseout(p){
    d3.selectAll("circle.someClass").classed("hide", true);
}
function click(p){
    d3.selectAll("circle.someClass").classed("hide", false);
}

2 个答案:

答案 0 :(得分:4)

如果您打算只有一个控制圆圈的元素,请使用"标记"。有条件地注册/取消注册事件并不是一个好主意。

检查小提琴的这个更新版本:

https://jsfiddle.net/cze9rqf7/

var svg = d3.select("#content")
          .append("svg")
          .attr("width", 600)
          .attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
          .text("Click me")
          .style("fill", "Blue")
          .attr("x", 50)
          .attr("y", 50)
          .on("mouseover", mouseover)
          .on("mouseout", mouseout)
          .on("click", click);

var circle = g.append("circle")
          .style("fill", "Orange")
          .attr("cx", 150)
          .attr("cy", 90)
          .attr("r", 15)
          .classed("hide", true)
          .classed("someClass", true);

var isClicked = false;

function mouseover(p){
    d3.selectAll("circle.someClass").classed("hide", false);
}

function mouseout(p){
    if(!isClicked) {
        d3.selectAll("circle.someClass").classed("hide", true);
    }
}

function click(p){
    isClicked = !isClicked;
    d3.selectAll("circle.someClass").classed("hide", false);
}

编辑评论

如果你需要"记住"每个元素的状态,而不是使用全局,你应该在这些元素上使用数据绑定:

var text = g.append("text")
  .datum({isClicked: false})
  .text("Click me")
  ...

function mouseout(p){
    // p is the data-bound object
    if(!p.isClicked) {
        var className = d3.select(this).attr("class");
        d3.selectAll("circle."+className).classed("hide", true);
  }
}

function click(p){
    // on click edit the data-bound object
    p.isClicked = !p.isClicked;
    var className = d3.select(this).attr("class");
    d3.selectAll("circle."+className).classed("hide", false);
}

更新了小提琴here

答案 1 :(得分:2)

这是一个没有任何"标志"的答案:

鉴于您有许多标签,一个选项是删除所点击元素的mouseout

d3.select(this).on("mouseout", null);

这是您更新的小提琴:https://jsfiddle.net/gerardofurtado/38p18pLt/

Stack代码段中的相同代码:



var svg = d3.select("body")
  .append("svg")
  .attr("width", 600)
  .attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
  .text("Click me")
  .style("fill", "Blue")
  .attr("x", 50)
  .attr("y", 50)
  .classed("someClass", true)
  .on("mouseover", mouseover)
  .on("mouseout", mouseout)
  .on("click", click);

var text2 = g.append("text")
  .text("Click me")
  .style("fill", "Blue")
  .attr("x", 50)
  .attr("y", 150)
  .classed("someClass2", true)
  .on("mouseover", mouseover)
  .on("mouseout", mouseout)
  .on("click", click);

var circle = g.append("circle")
  .style("fill", "Orange")
  .attr("cx", 150)
  .attr("cy", 90)
  .attr("r", 15)
  .classed("hide", true)
  .classed("someClass", true);

var circle2 = g.append("circle")
  .style("fill", "Green")
  .attr("cx", 250)
  .attr("cy", 90)
  .attr("r", 15)
  .classed("hide", true)
  .classed("someClass2", true);

function mouseover(p) {
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", false);
}

function mouseout(p) {
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", true);
}

function click(p) {
  d3.select(this).on("mouseout", null);
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", false);
}

.hide {
  display: none;
}

text {
  cursor: pointer;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;

您还可以切换点击,让mouseout再次发挥作用:

if(d3.select(this)[0][0].__onmouseout){
    d3.select(this).on("mouseout", null);
} else {
    d3.select(this).on("mouseout", mouseout);
}

这是&#34;切换&#34;的小提琴。功能:https://jsfiddle.net/gerardofurtado/4zb9gL9r/1/

Stack代码段中的相同代码:

&#13;
&#13;
var svg = d3.select("body")
  .append("svg")
  .attr("width", 600)
  .attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
  .text("Click me")
  .style("fill", "Blue")
  .attr("x", 50)
  .attr("y", 50)
  .classed("someClass", true)
  .on("mouseover", mouseover)
  .on("mouseout", mouseout)
  .on("click", click);

var text2 = g.append("text")
  .text("Click me")
  .style("fill", "Blue")
  .attr("x", 50)
  .attr("y", 150)
  .classed("someClass2", true)
  .on("mouseover", mouseover)
  .on("mouseout", mouseout)
  .on("click", click);

var circle = g.append("circle")
  .style("fill", "Orange")
  .attr("cx", 150)
  .attr("cy", 90)
  .attr("r", 15)
  .classed("hide", true)
  .classed("someClass", true);

var circle2 = g.append("circle")
  .style("fill", "Green")
  .attr("cx", 250)
  .attr("cy", 90)
  .attr("r", 15)
  .classed("hide", true)
  .classed("someClass2", true);

function mouseover(p) {
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", false);
}

function mouseout(p) {
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", true);
}

function click(p) {
  if (d3.select(this)[0][0].__onmouseout) {
    d3.select(this).on("mouseout", null);
  } else {
    d3.select(this).on("mouseout", mouseout);
  }
  var className = d3.select(this).attr("class");
  d3.selectAll("circle." + className).classed("hide", false);
}
&#13;
.hide {
  display: none;
}

text {
  cursor: pointer;
}
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
&#13;
&#13;
&#13;