从d3

时间:2015-07-02 17:10:54

标签: javascript d3.js

我怀疑是关于d3如何工作的一个相当基本的问题。我已经开始使用这个完美运行的代码并触发nodeClick动作...

var nodeEnter = node.enter()
                        .append("g")
                        .attr("class", "node")
                        .on("click", nodeClick)

但后来我改为使用点击功能来确定是单击还是双击......

.on("click", function(d) {
                            if some logic ()  {
                               console.log("double click");
                            } else {
                                console.log("single click only");
                                nodeClick;
                            }
                        })

这在输出正确的控制台消息方面非常有效,但似乎我对nodeClick的调用在嵌入到函数中时无法正常工作(即不触发节点点击行为)。我尝试更改为nodeClick()和nodeClick(d),但这只会导致错误。

我错过了可以解释这种行为的东西吗?对我来说似乎很奇怪,我看到了从函数外部和内部调用“nodeClick”的两种不同行为。

感谢您的帮助!

这是完整的代码......

dblclick_timer = false;
//.on("click", nodeClick) //works perfectly
.on("click", function(d) {
    if ( dblclick_timer )  {
        clearTimeout(dblclick_timer)
        dblclick_timer = false
        console.log("double click");
        d.fixed=false;
    }
    else dblclick_timer = setTimeout( function(){
                            dblclick_timer = false
                            console.log("single click only");
                            d3.select(this).nodeClick;
                        }, 250)
})

经过所有很好的反馈,这是通过在d3.event变为空之前存储它的工作解决方案......

.on("click", function(d,i) {
                            var cacheEvent = d3.event;
                            if ( dblclick_timer )  {
                                clearTimeout(dblclick_timer)
                                dblclick_timer = false
                                console.log("double click");
                                d.fixed=false;
                                force.start(); 
                            }
                            else dblclick_timer = setTimeout( function(){
                                dblclick_timer = false
                                console.log("single click only");
                                d3.event = cacheEvent;
                                nodeClick.call(d3.select(this), d, i);
                            }, 250)
                        })

2 个答案:

答案 0 :(得分:2)

如第一条评论所述,你必须建立正确的上下文:它是一个javaScript的东西,而不是d3的东西。如果您建立了正确的this上下文并传递相同的参数,它将完全相同。关键是使用Function.prototype.call来调用回调。这是standard javaScript

.on("click", function(d, i) {
                            if some logic ()  {
                               console.log("double click");
                            } else {
                                console.log("single click only");
                                nodeClick.call(this, d, i);
                            }
                        })  

documents

中所述
  

以与其他运算符相同的方式调用指定的侦听器   函数,传递当前数据d和索引i,用这个   context作为当前的DOM元素。

答案 1 :(得分:1)

正如评论中指出的那样,您实际上并没有调用该函数。在案件中

.on("click", nodeClick)

安装函数nodeClick()作为click事件的处理程序。这里nodeClick引用函数对象 - 即函数本身,而不是它可能为特定输入返回的任何值。

在第二种情况下,你做同样的事情,除了你传入匿名(即在现场定义)功能而不是命名功能。在这两种情况下,都会在事件发生时调用该函数。

语句nodeClick;本身没有任何效果 - 它与1;foo;基本相同,其中foo是其他地方定义的变量或函数。

要使其工作,您需要调用该函数 - 在名称后添加()。此外,您需要传递回调收到的任何参数 - nodeClick(d)。您还需要使用相同的this上下文来调用它,因为函数的实现依赖于它。如果您使用selection.each()

,所有这些都是为您完成的
d3.select(this).each(nodeClick);