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

标签 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 也始终为 null。

但是,如果您注释掉第 13 行和 mousedownmouseupon 注册>14 分别:

 g.on("mousedown", mousedown)
         .on("mouseup", mouseup)
         .on("click", clicked)
         .on("dblclick", doubleClicked);

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

最佳答案

您在检查 longTimermouseup 处理程序中将 clickTimer 设置为 null。纠正该行为即可修复该行为。

关于javascript - 当 mousedown/mouseup 注册时,双击计时器始终为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28588871/

相关文章:

javascript - 使用 iframe-resizer : iframe grows when I click inside iframe, 在移动设备上也不起作用

javascript - 尝试通过模拟管道函数来测试文件检索

javascript - 悬停时的 D3.js 工具提示

javascript - D3js使y轴高度100

javascript - HTMLcollection 0 列表长度,[n]返回undefined,转换为数组返回空数组

javascript - 从 d3 力定向图的数组中删除重复边

javascript - 如何使用 localhost 演示 SOP 的利用

javascript - Jest spy 不能在不同的目录中工作吗?

javascript - 禁用 JavaScript 的浏览器是否会禁用内联 JavaScript?

javascript - 简单函数在 if 语句中不起作用