当mousedown / mouseup注册时,双击定时器总是为null [英] Double click timer is always null when mousedown/mouseup registered

查看:110
本文介绍了当mousedown / mouseup注册时,双击定时器总是为null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个可重复使用的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 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆