我正在尝试创建一个可重复使用的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 行注释了on
或mousedown
的{{1}}注册:< / p>
mouseup
然后一切都按预期工作,但我似乎无法发现这两个功能的任何副作用。我错过了一些明显的东西吗?
答案 0 :(得分:2)
您要在clickTimer
处理程序中null
设置mouseup
longTimer
,然后再检查{{1}}。更正可修复行为。