当mousedown / mouseup注册时,双击定时器总是为null [英] Double click timer is always null when mousedown/mouseup registered
问题描述
我想创建一个可重复使用的D3事件函数,该函数会为点击次数和双击次数提供一些更丰富的事件。这个想法是双击不应该单击。我设法让这个工作,但现在我介绍了第三方面(长时间点击)的基本行为似乎是打破,我不能弄清楚为什么。
var custom = {}; custom.events = function(){var clickTimeout = 3000; //用于区分单击和双击的超时时间var longClickTimeout = 1000; //用于识别长按的超时var clickTimer; //用于单击事件的计时器var longTimer; //长按下的定时器var dispatch = d3.dispatch(click,dblclick,longclick,mousedown,mouseup);函数事件(g){g.on(mousedown,mousedown).on(mouseup,mouseup).on(click,clicked).on(dblclick,doubleClicked); }; / ** *单击项目时调用的函数。此函数*处理单个和双击样式事件的高级行为和农场外调用* @params {object} d - D3基准* @aparams {number} i - 基准点* /函数的点击,i){if(d3.event.defaultPrevented)return; //忽略是否正在进行拖动操作d3.event.stopPropagation(); //阻止事件进一步//如果我们已经有一个定时器,那么我们需要执行一个双击行为事件console.log(Click Timer:+ clickTimer); if(clickTimer){console.log(Clearing Click Timer:+ clickTimer); clearTimeout(clickTimer); clickTimer = null; dispatch.dblclick.call(this,d,i);返回; } //设置单击的计时器clickTimer = setTimeout(function(){//触发单击clickTimer = null; dispatch.click.call(this,d,i);},clickTimeout); console.log(Creating Click Timer:+ clickTimer); }; / * *双击项目时调用的函数。在这种情况下,函数只是抑制* / function doubleClicked(d,i){//抑制自然双击事件d3.event.stopPropagation(); };函数mousedown(d,i){//设置长按计时器longTimer = setTimeout(function(){longClickTimeout = null; dispatch.longclick.call(this,d,i);},longClickTimeout); console.log(Creating Long Timer:+ longTimer); //触发鼠标按下事件dispatch.mousedown.call(this,d,i); } function mouseup(d,i){//取消长定时器(如果需要,应该已经触发)if(longTimer){console.log(Clearing Long Timer:+ longTimer); clearTimeout(longTimer); clickTimer = null; } dispatch.mouseup.call(this,d,i); } //返回绑定事件return d3.rebind(events,dispatch,on);}; var events = custom.events()。on(click,function(){console.log ;})。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);
pre class =snippet-code-html lang-html prettyprint-override> < script src =https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3 .min.js>
你可以在上面的代码片段中看到我把我的调试输出放在一起。如果您尝试双击控制台可见的圆圈,似乎 clickTimer
始终为null,即使双击。
但是,如果您注释了注册
mousedown $ c $分别在行 13 和 14 上分别显示
mouseup
:
g.on(mousedown,mousedown)
.on(mouseup,mouseup)
.on $ b .on(dblclick,doubleClicked);
那么一切都按预期工作,但是我似乎没有发现这两个函数的任何副作用。
您正在设置 clickTimer
到 mouseup
处理程序中检查 longTimer
的 null
>。更正会修正行为。
I'm trying to create a re-usable D3 events function that provides some slightly richer eventing regarding clicks + double clicks. The idea being that a double click should not fire a single click. I managed to get that working, but now I've introduced a 3rd aspect (the long click) the basic behavior seems to be breaking and I can't figure out why.
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>
You can see in the above code snippet what I've put together, with my debugging output in there. If you try double clicking on the circle with the console visible it seems as though the clickTimer
is always null even when double clicking.
If however you comment out the on
registration for either mousedown
or mouseup
on lines 13 and 14 respectively:
g.on("mousedown", mousedown)
.on("mouseup", mouseup)
.on("click", clicked)
.on("dblclick", doubleClicked);
then everything works as expected, however I can't seem to spot any side affects of the two functions. Am I missing something obvious here?
You're setting clickTimer
to null
in the mouseup
handler where you're checking longTimer
. Correcting that fixes the behaviour.
这篇关于当mousedown / mouseup注册时,双击定时器总是为null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!