【问题标题】:How to detect a double-click-drag in Javascript/jQuery如何检测 Javascript/jQuery 中的双击拖动
【发布时间】:2014-01-30 13:19:46
【问题描述】:

当用户通过拖动选择某些文本时,我想在网页中进行检测。但是,在 Windows 中有一种情况,我称之为“双击拖动”(抱歉,如果我不知道已经有更好的名称),我不知道如何检测它。它是这样的:

  1. 按下鼠标键
  2. 快速松开鼠标键
  3. 再次快速按下鼠标键
  4. 按住按钮拖动

这会导致拖动选择整个单词。从用户的角度来看,这是一种非常有用的技术。

我要做的是区分双击拖动和单击然后单独拖动之间的区别。因此,当我进入第 2 步时,我会收到一个点击事件,但我不想将其视为点击;我想看看他们是否要立即执行第 3 步。

据推测,Windows 会根据时间以及鼠标在第 2 步和第 3 步之间移动了多少来检测到这一点,但我不知道它使用的参数,所以我无法复制 Windows 逻辑。请注意,即使鼠标在第 2 步和第 3 步之间根本没有移动,我仍然会收到 mousemove 事件。

我意识到我应该设计触摸友好和设备中立的界面,并且我完全打算支持其他设备,但这是一个针对 Windows PC 用户的企业应用程序,所以我想优化这个案例如果可以的话。

【问题讨论】:

  • 这可能会有所帮助stackoverflow.com/questions/9950042/… 尽管您需要根据需要对其进行修改。
  • 我不确定我明白了,但是如果你在浏览器中双击一个单词,它不是默认选中的,所以你真正需要做的就是包装文本选择并使其可拖动?

标签: javascript jquery jquery-events


【解决方案1】:

我们也做过类似的事情。我们的最终解决方案是创建一个抑制默认响应的单击处理程序,然后将全局变量设置为当前日期/时间。然后我们设置另一个函数在大约 200 毫秒内触发,以处理“点击”事件。那是我们的基本功能。

然后我们对其进行了修改以查看全局变量以确定最后一次点击发生的时间。如果小于 200 毫秒(根据您的需要进行修改),我们会设置一个标志,该标志会导致单击处理程序失败并称为双击处理程序。

您可以通过让单击和双击处理程序手动触发拖动功能来扩展该方法。

我现在无法访问上述代码,但这里有一个该框架用于跟踪键盘点击以确定扫描仪或用户是否已完成输入字段的示例:

    var lastKeyPress    = loadTime.getTime();

    // This function fires on each keypress while the cursor is in the field.  It checks the field value for preceding and trailing asterisks, which
    // denote use of a scanner.  If these are found it cleans the input and clicks the add button.  This function also watches for rapid entry of keyup events, which 
    // also would denote a scanner, possibly one that does not use asterisks as control characters.
    function checkForScanKeypress() {
        var iVal = document.getElementById('field_id').value;

        var currentTime = new Date()
        var temp        = currentTime.getTime();
        if (temp - lastKeyPress < 80) {
            scanCountCheck = scanCountCheck + 1;
        } else {
            scanCountCheck = 0;
        }
        lastKeyPress    = currentTime.getTime();
    }


    // The script above tracks how many successive times two keyup events have occurred within 80 milliseconds of one another.  The count is reset
    // if any keypress occurs more than 80 milliseconds after the last (preventing false positives from manual entry).  The script below runs
    // every 200 milliseconds and looks to see if more than 3 keystrokes have occurred in such rapid succession.  If so, it is assumed that a scanner
    // was used for this entry.  It then waits until at least 200 milliseconds after the last event and then triggers the next function.
    // The 200ms buffer after the last keyup event insures the function is not called before the scanner completes part number entry.
    function checkForScan() {
        var currentTime = new Date();
        var temp        = currentTime.getTime();
        if (temp - lastKeyPress > 200 && scanCountCheck > 3) {
            FiredWhenUserStopsTyping();
            scanCountCheck = 0;
        }
        setTimeout(checkForScan, 200);
    }

这是我刚刚根据上述想法编写的一些代码。它未经测试,不包含实际的拖动事件,但应该给你一个很好的起点:

    var lastClick   = loadTime.getTime();

    function fireOnClickEvent(event) {
        event.preventDefault;

        var currentTime = new Date()
        var temp        = currentTime.getTime();
        if (temp - lastClick < 80) {
            clearTimeout(tf);
            doubleClickHandler();
        } else {
            tf          = setTimeout(singleClickHandler, 100);
        }
        lastClick       = currentTime.getTime();
    }

    function singleClickHandler() {
        // Begin normal drag function
    }

    function doubleClickHandler() {
        // Begin alternate drag function
    }

【讨论】:

  • 谢谢。我希望我不必求助于这种低级别的点击检测,因为你在猜测用户的 PC 设置的双击速度,但由于缺乏其他回复,我想没有简单的解决方案.
  • 不幸的是,我们找不到任何东西。我认为我们遇到了一些库和其他更结构化的方法,但不存在兼容性,尤其是与旧浏览器的兼容性。这是我们能想出的解决问题的最佳方法。对不起。
【解决方案2】:

单个双击拖拽动作依次涉及以下事件:

mousedown -> mouseup -> click -> mousedown -> mousemove

考虑到这一点,我想出了这个简单的解决方案:

let maybeDoubleClickDragging = false;
    let maybeDoubleClickDraggingTimeout;
    const element = document.querySelector('#container');

    element.addEventListener("click", function (e) {
      maybeDoubleClickDragging = true;
      element.removeEventListener("mousemove", handleMousemove);

    });

    element.addEventListener("mousedown", (e) => {
      element.addEventListener("mousemove", handleMousemove);

      if (maybeDoubleClickDragging) {
        clearTimeout(maybeDoubleClickDraggingTimeout);
        return;
      }
    });

    element.addEventListener("mouseup", (event) => {
      maybeDoubleClickDraggingTimeout = setTimeout(() => {
        maybeDoubleClickDragging = false;
      }, 200);
    });

    function handleMousemove(e) {
       if(maybeDoubleClickDragging) {
       element.textContent = 'you are double-click-dragging'
       }
    
    }
#container {
 width: 300px;
 height: 300px;
 background: yellow;
 }
&lt;div id="container"&gt;&lt;/div&gt;

【讨论】:

    猜你喜欢
    • 2015-06-23
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 2015-12-01
    • 2012-04-14
    • 2011-01-14
    • 2015-11-09
    相关资源
    最近更新 更多