当mousedown / mouseup注册时,双击计时器始终为空

时间:2015-02-18 16:39:47

标签: javascript d3.js

我正在尝试创建一个可重复使用的D3事件功能,它提供了一些关于点击+双击的稍微丰富的事件。这个想法是双击不应该点击一次。我设法让它工作,但现在我已经介绍了第三个方面(长按)基本行为似乎正在打破,我无法弄清楚为什么。

var custom = { };
custom.events = function () {

    var clickTimeout = 3000;        // The timeout that is used to distinguish between a single and double click
    var longClickTimeout = 1000;    // The timeout that is used to identify a long press
    var clickTimer;                 // The timer that is used for a single click event
    var longTimer;                  // The timer for a long press

    var dispatch = d3.dispatch("click", "dblclick", "longclick", "mousedown", "mouseup");

    function events(g) {
  
        g.on("mousedown", mousedown)
         .on("mouseup", mouseup)
         .on("click", clicked)
         .on("dblclick", doubleClicked);
    };

    /**
     * Function that's called when an item is clicked. This function
     * handles the advanced behaviour and farms out calls for both single
     * and double click style events
     * @params {object} d - The D3 datum
     * @aparams {number} i - The index of the datum
     */
    function clicked(d, i) {
        
        if (d3.event.defaultPrevented) return;      // Ignore if a drag operation is taking place
        d3.event.stopPropagation();                 // Prevent the event going any further

        // If we already have a timer then we need to execute
        // a double click behaviour event
        console.log("Click Timer : " + clickTimer);
        if (clickTimer) {
            console.log("Clearing Click Timer : " + clickTimer);
            clearTimeout(clickTimer);
            clickTimer = null;
            dispatch.dblclick.call(this, d, i);
            return;
        }

        // Setup the timer for single click
        clickTimer = setTimeout(function () {
            // Trigger a single click
            clickTimer = null;
            dispatch.click.call(this, d, i);
        }, clickTimeout);
        console.log("Creating Click Timer : " + clickTimer);
    };

    /*
     * Function that's called when an item is double clicked. In
     * this case the function is just suppressed
     */
    function doubleClicked(d, i) {
        // Suppress the natural double click event
        d3.event.stopPropagation();
    };

    function mousedown(d, i) {
        // Set up the long press timer
        longTimer = setTimeout(function () {
            longClickTimeout = null;
            dispatch.longclick.call(this, d, i);
        }, longClickTimeout);

        console.log("Creating Long Timer : " + longTimer);
        // Trigger a mouse down event
        dispatch.mousedown.call(this, d, i);
    }

    function mouseup(d, i) {
        // Cancel the long timer (it should have already fired if it needed to)
        if (longTimer) {
            console.log("Clearing Long Timer : " + longTimer);
            clearTimeout(longTimer);
            clickTimer = null;
        }

        dispatch.mouseup.call(this, d, i);
    }

    // Return the bound events
    return d3.rebind(events, dispatch, "on");
};

var events = custom.events()
.on("click", function() { console.log("click"); })
.on("dblclick", function() { console.log("dblclick"); });

d3.select("svg")
.append("circle")
.attr("r", 150)
.attr("cx", 150)
.attr("cy", 150)
.style("fill", "red")
.call(events);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="500" height="500"></svg>

你可以在上面的代码片段中看到我放在一起的内容,我的调试输出在那里。如果您尝试双击控制台可见的圆圈,即使双击,clickTimer似乎也始终为空。

但是,如果您分别在 13 14 行注释了onmousedown的{​​{1}}注册:< / p>

mouseup

然后一切都按预期工作,但我似乎无法发现这两个功能的任何副作用。我错过了一些明显的东西吗?

1 个答案:

答案 0 :(得分:2)

您要在clickTimer处理程序中null设置mouseup longTimer,然后再检查{{1}}。更正可修复行为。