简体   繁体   English

如何在 JavaScript 中监听三次点击?

[英]How do I listen for triple clicks in JavaScript?

If this is for a double-click:如果这是双击:

window.addEventListener("dblclick", function(event) { }, false);

How can I capture a triple-click?如何捕捉三次点击? This is for a pinned tab in Google Chrome.这是针对 Google Chrome 中的固定选项卡。

You need to write your own triple-click implementation because no native event exists to capture 3 clicks in a row. 您需要编写自己的三击实现,因为不存在连续捕获3次点击的本机事件。 Fortunately, modern browsers have event.detail , which the MDN documentation describes as : 幸运的是,现代浏览器有event.detailMDN文档描述为

A count of consecutive clicks that happened in a short amount of time, incremented by one. 在短时间内发生的连续点击次数,递增1。

This means you can simply check the value of this property and see if it is 3 : 这意味着您只需检查此属性的值并查看它是否为3

window.addEventListener('click', function (evt) {
    if (evt.detail === 3) {
        alert('triple click!');
    }
});

Working demo: http://jsfiddle.net/L6d0p4jo/ 工作演示: http//jsfiddle.net/L6d0p4jo/


If you need support for IE 8, the best approach is to capture a double-click, followed by a triple-click — something like this, for example: 如果您需要支持IE 8,最好的方法是捕获双击,然后进行三次单击 - 例如:

var timer,          // timer required to reset
    timeout = 200;  // timer reset in ms

window.addEventListener("dblclick", function (evt) {
    timer = setTimeout(function () {
        timer = null;
    }, timeout);
});
window.addEventListener("click", function (evt) {
    if (timer) {
        clearTimeout(timer);
        timer = null;
        executeTripleClickFunction();
    }
});

Working demo: http://jsfiddle.net/YDFLV/ 工作演示: http//jsfiddle.net/YDFLV/

The reason for this is that old IE browsers will not fire two consecutive click events for a double click. 原因是旧的IE浏览器不会触发两次连续点击事件进行双击。 Don't forget to use attachEvent in place of addEventListener for IE 8. 不要忘记使用attachEvent代替IE 8的addEventListener

Since DOM Level 2 you could use mouse click handler and check the detail parameter of event which should be interpreted as: 从DOM Level 2开始,您可以使用鼠标单击处理程序并检查事件的detail参数,该参数应解释为:

The detail attribute inherited from UIEvent indicates the number of times a mouse button has been pressed and released over the same screen location during a user action. 从UIEvent继承的detail属性指示在用户操作期间在同一屏幕位置上按下和释放鼠标按钮的次数。 The attribute value is 1 when the user begins this action and increments by 1 for each full sequence of pressing and releasing. 当用户开始此操作时,属性值为1,并且对于按下和释放的每个完整序列,属性值增加1。 If the user moves the mouse between the mousedown and mouseup the value will be set to 0, indicating that no click is occurring. 如果用户在mousedown和mouseup之间移动鼠标,则该值将设置为0,表示没有发生单击。

So the value of detail === 3 will give you the triple-click event. 因此, detail === 3的值将为您提供三击事件。

More information in specification at http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent . 有关规范的更多信息, 请参见http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-MouseEvent

Thanks to @Nayuki https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail - a DOM3 extension which is WIP https://w3c.github.io/uievents/ 感谢@Nayuki https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail - 一个DOM3扩展,它是WIP https://w3c.github.io/uievents/

Here is the real Triple click event, which triggers only when all of three clicks fired with equal interval. 这是真正的三击事件,只有当所有三次点击以相等的间隔触发时才触发。

 // Default settings var minClickInterval = 100, maxClickInterval = 500, minPercentThird = 85.0, maxPercentThird = 130.0; // Runtime var hasOne = false, hasTwo = false, time = [0, 0, 0], diff = [0, 0]; $('#btn').on('click', function() { var now = Date.now(); // Clear runtime after timeout fot the 2nd click if (time[1] && now - time[1] >= maxClickInterval) { clearRuntime(); } // Clear runtime after timeout fot the 3rd click if (time[0] && time[1] && now - time[0] >= maxClickInterval) { clearRuntime(); } // Catch the third click if (hasTwo) { time[2] = Date.now(); diff[1] = time[2] - time[1]; var deltaPercent = 100.0 * (diff[1] / diff[0]); if (deltaPercent >= minPercentThird && deltaPercent <= maxPercentThird) { alert("Triple Click!"); } clearRuntime(); } // Catch the first click else if (!hasOne) { hasOne = true; time[0] = Date.now(); } // Catch the second click else if (hasOne) { time[1] = Date.now(); diff[0] = time[1] - time[0]; (diff[0] >= minClickInterval && diff[0] <= maxClickInterval) ? hasTwo = true : clearRuntime(); } }); var clearRuntime = function() { hasOne = false; hasTwo = false; time[0] = 0; time[1] = 0; time[2] = 0; diff[0] = 0; diff[1] = 0; }; 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> Click button three times with equal interval <button id="btn">Click me</button> 

Also, I wrote jquery plugin TrplClick , which enables 'trplclick' event 另外,我编写了jquery插件TrplClick ,它启用了'trplclick'事件

it's very simple if you do it right, and you can even catch single, double, triple, ... clicks as you like. 如果你做得对,这很简单,你甚至可以随心所欲地捕捉单次,双次,三次......点击。 plain javascript, customizable click delay (timeout): 普通的javascript,可定制的点击延迟(超时):

var clicks = 0;
var timer, timeout = 350; // time between each click

var doubleClick = function(e) {
  console.log('doubleClick');
}

var tripleClick = function(e) {
  console.log('tripleClick');
}

// click timer
yourcontainer.addEventListener('click', function(e) {
  clearTimeout(timer);
  clicks++;
  var evt = e;
  timer = setTimeout(function() {
    if(clicks==2) doubleClick(evt);
    if(clicks==3) tripleClick(evt);
    clicks = 0;
  }, timeout);
});

pseudo-code: 伪代码:

var clicks = 0

onclick:
clicks++;
setTimer(resetClicksToZero);
if clicks == 3: tripleclickdetected(); clicks = 0;

I am working on a javascript code editor and I had to listen for triple click and here is the solution that will work for most browsers: 我正在开发一个javascript代码编辑器,我不得不听三重点击,这里的解决方案适用于大多数浏览器:

// Function to get mouse position
var getMousePosition = function (mouseEvent) {
    var currentObject = container;
    var currentLeft = 0;
    var currentTop = 0;
    do {
        currentLeft += currentObject.offsetLeft;
        currentTop += currentObject.offsetTop;
        currentObject = currentObject.offsetParent;
    } while (currentObject != document.body);
    return {
        x: mouseEvent.pageX - currentLeft,
        y: mouseEvent.pageY - currentTop
    }
}

// We will need a counter, the old position and a timer
var clickCounter = 0;
var clickPosition = {
    x: null,
    y: null
};
var clickTimer;

// The listener (container may be any HTML element)
container.addEventListener('click', function (event) {

    // Get the current mouse position
    var mousePosition = getMousePosition(event);

    // Function to reset the data
    var resetClick = function () {
        clickCounter = 0;
        var clickPosition = {
            x: null,
            y: null
        };
    }

    // Function to wait for the next click
    var conserveClick = function () {
        clickPosition = mousePosition;
        clearTimeout(clickTimer);
        clickTimer = setTimeout(resetClick, 250);
    }

    // If position has not changed
    if (clickCounter && clickPosition.x == mousePosition.x && clickPosition.y == mousePosition.y) {
        clickCounter++;
        if (clickCounter == 2) {
            // Do something on double click
        } else {
            // Do something on triple click
            resetClick();
        }
        conserveClick();
    } else {
        // Do something on single click
        conserveClick();
    }
});

Tested on Firefox 12, Google Chrome 19, Opera 11.64, Internet Explorer 9 在Firefox 12,Google Chrome 19,Opera 11.64,Internet Explorer 9上测试过

This approach checks if the user has not changed cursor's position, you still can do something when you have single click or double click. 此方法检查用户是否未更改光标位置,单击或双击时仍可执行某些操作。 Hope this solution will help everybody who will need to implement a triple click event listener :) 希望这个解决方案能够帮助每个需要实现三击事件监听器的人:)

Configurable n-clicks event detector factory可配置的 n-clicks 事件检测器工厂

const nClicks = (minClickStreak, maxClickInterval = 500, resetImmediately = true) => {
  let timerId = 0
  let clickCount = 0
  let lastTarget = null
  const reset = () => {
    timerId = 0
    clickCount = 0
    lastTarget = null
  }
  
  return (originalEventHandler) => (e) => {
    if (lastTarget == null || lastTarget == e.target) { // 2. unless we clicked same target
      clickCount++ // 3. then increment click count
      clearTimeout(timerId)
    }
    lastTarget = e.target
    timerId = setTimeout(reset, maxClickInterval) // 1. reset state within set time
    if (clickCount >= minClickStreak) {
      originalEventHandler(e)
      if (resetImmediately) {
        clickCount = 0
      }
    }
  }
  
}

Usage用法

  table.addEventListener('click', nClicks(2)(e => { // double click
    selectCell(e.target)
  }))

  table.addEventListener('click', nClicks(3)(e => { // triple click
    selectRow(e.target)
  }))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM