繁体   English   中英

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

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

如果这是双击:

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

如何捕捉三次点击? 这是针对 Google Chrome 中的固定选项卡。

您需要编写自己的三击实现,因为不存在连续捕获3次点击的本机事件。 幸运的是,现代浏览器有event.detailMDN文档描述为

在短时间内发生的连续点击次数,递增1。

这意味着您只需检查此属性的值并查看它是否为3

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

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


如果您需要支持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();
    }
});

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

原因是旧的IE浏览器不会触发两次连续点击事件进行双击。 不要忘记使用attachEvent代替IE 8的addEventListener

从DOM Level 2开始,您可以使用鼠标单击处理程序并检查事件的detail参数,该参数应解释为:

从UIEvent继承的detail属性指示在用户操作期间在同一屏幕位置上按下和释放鼠标按钮的次数。 当用户开始此操作时,属性值为1,并且对于按下和释放的每个完整序列,属性值增加1。 如果用户在mousedown和mouseup之间移动鼠标,则该值将设置为0,表示没有发生单击。

因此, detail === 3的值将为您提供三击事件。

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

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

这是真正的三击事件,只有当所有三次点击以相等的间隔触发时才触发。

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

另外,我编写了jquery插件TrplClick ,它启用了'trplclick'事件

如果你做得对,这很简单,你甚至可以随心所欲地捕捉单次,双次,三次......点击。 普通的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);
});

伪代码:

var clicks = 0

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

我正在开发一个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();
    }
});

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

此方法检查用户是否未更改光标位置,单击或双击时仍可执行某些操作。 希望这个解决方案能够帮助每个需要实现三击事件监听器的人:)

可配置的 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
      }
    }
  }
  
}

用法

  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