简体   繁体   中英

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.

You need to write your own triple-click implementation because no native event exists to capture 3 clicks in a row. Fortunately, modern browsers have event.detail , which the MDN documentation describes as :

A count of consecutive clicks that happened in a short amount of time, incremented by one.

This means you can simply check the value of this property and see if it is 3 :

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

Working demo: 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:

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();
    }
});

The reason for this is that old IE browsers will not fire two consecutive click events for a double click. Don't forget to use attachEvent in place of addEventListener for IE 8.

Since DOM Level 2 you could use mouse click handler and check the detail parameter of event which should be interpreted as:

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. The attribute value is 1 when the user begins this action and increments by 1 for each full sequence of pressing and releasing. If the user moves the mouse between the mousedown and mouseup the value will be set to 0, indicating that no click is occurring.

So the value of detail === 3 will give you the triple-click event.

More information in specification at 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/

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

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):

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:

// 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

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

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)
  }))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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