Предотвратить срабатывание события click при возникновении события dblclick - PullRequest
28 голосов
/ 19 мая 2009

Я обрабатываю события click и dblclick для элемента DOM. Каждый из них выполняет свою команду, но я обнаружил, что при двойном щелчке на элементе, в дополнение к событию двойного щелчка, событие щелчка также запускается дважды. Каков наилучший подход для предотвращения такого поведения?

Ответы [ 9 ]

23 голосов
/ 01 мая 2015

В случае, если кто-то еще наткнется на этот (как я) поиск ответа, самое лучшее решение, которое я мог бы найти, заключается в следующем:

    $node.on('click',function(e){
      if(e.originalEvent.detail > 1){
         return;
        /* if you are returning a value from this
         function then return false or cancel 
         the event some other way */
      }
    });

Готово. Если имеется более одного щелчка подряд, второй, третий и т. Д. не будет стрелять Я определенно предпочитаю использовать таймеры любого типа.

Я указал себе в этом направлении, прочитав это .


Между прочим: я впервые исследовал эту проблему, потому что я случайно дважды щелкнул по нумерованной ссылке, и событие сработало и завершилось дважды, прежде чем мог произойти обратный вызов.

Прежде чем приступить к приведенному выше коду, у меня было

 if e.originalEvent.detail === 2 //return

однако мне удалось щелкнуть ссылку 3 раза (тройной щелчок), и, хотя второй щелчок не сработал, третий сделал

13 голосов
/ 19 мая 2009

В комментарии вы сказали,

Я задерживаю обработчик кликов на 300 мс (заметная и раздражающая задержка) и даже ...

Похоже, вы хотите, чтобы при щелчке DOM немедленно генерировал событие щелчка, кроме случаев, когда щелчок является первым щелчком двойного щелчка.

Чтобы реализовать эту функцию, при щелчке DOM должен быть в состоянии предсказать, является ли это последним щелчком или первым двойным щелчком (однако я не думаю, что это вообще возможно DOM, чтобы предсказать, собирается ли пользователь снова щелкнуть).


Какие два различных действия вы пытаетесь выполнить при щелчке и двойном щелчке? ИМО, в обычном приложении вы можете захотеть оба события: например, щелкните один раз, чтобы сфокусироваться на элементе, а затем дважды щелкните, чтобы активировать его.

Когда вам необходимо разделить события, некоторые приложения используют что-то, кроме двойного щелчка: например, они используют щелчок правой кнопкой мыши или нажатие клавиши управления.

5 голосов
/ 19 мая 2009

В этом случае лучше всего немного задержать выполнение события одного клика. Сделайте так, чтобы ваш обработчик двойного щелчка установил переменную, которую будет проверять событие одиночного щелчка. Если эта переменная имеет определенное значение, может быть boolDoubleClick == true, то не fire/handle один клик.

4 голосов
/ 24 марта 2018

Вы можете использовать UIEvent.detail, если хотите определить, сколько раз был нажат элемент, и инициировать события на его основе.

Простой пример:

element.addEventListener("click", function (e) {
  if (e.detail === 1) {
    // do something if the element was clicked once.
  } else if (e.detail === 2) {
    // do something else if the element was clicked twice
  }
});
3 голосов
/ 14 февраля 2013

Вот что я сделал, чтобы различить в модуле

       node.on('click', function(e) {

            //Prepare for double click, continue to clickHandler doesn't come soon enough
            console.log("cleared timeout in click",_this.clickTimeout);
            clearTimeout(_this.clickTimeout);
            _this.clickTimeout = setTimeout(function(){
                console.log("handling click");
                _this.onClick(e);
            },200);
            console.log(_this.clickTimeout);
        });

        node.on('dblclick', function (e) {

            console.log("cleared timeout in dblclick",_this.clickTimeout);
            clearTimeout(_this.clickTimeout);
            // Rest of the handler function
3 голосов
/ 29 июня 2009

AFAIK DOM Level 2 Events не содержит спецификации для двойного щелчка. Это не работает для меня в IE7 (это шок), но у FF и Opera нет проблем с управлением спецификацией, где я могу прикрепить все действия к событию click, но для двойного щелчка просто подождите, пока не появится атрибут "detail" объекта события - 2. Из документов: «Если в одном и том же месте экрана происходит несколько щелчков, последовательность повторяется с атрибутом подробности, увеличивающимся с каждым повторением.»

2 голосов
/ 16 июня 2012

Благодаря всем остальным ответам здесь, поскольку их сочетание, кажется, дает мне разумное решение, когда взаимодействие требует обоих, но взаимоисключающих:

var pendingClick = 0;

function xorClick(e) {
    // kill any pending single clicks
    if (pendingClick) {
        clearTimeout(pendingClick);
        pendingClick = 0;
    }

    switch (e.detail) {
        case 1:
            pendingClick = setTimeout(function() {
                console.log('single click action here');
            }, 500);// should match OS multi-click speed
            break;
        case 2:
            console.log('double click action here');
            break;
        default:
            console.log('higher multi-click actions can be added as needed');
            break;
    }
}

myElem.addEventListener('click', xorClick, false);

Обновление: Я добавил обобщенную версию этого подхода вместе с полифиллом для сенсорных устройств в этом репозитории Github с примерами:

https://github.com/mckamey/doubleTap.js

0 голосов
/ 28 мая 2019

  const toggle = () => {
      watchDouble += 1;
      setTimeout(()=>{
        if (watchDouble === 2) {
          console.log('double' + watchDouble)
        } else if (watchDouble === 1) {
          console.log("signle" + watchDouble)
        }
        watchDouble = 0
      },200);

  }
0 голосов
/ 21 ноября 2017

Я знаю, что это чертовски старо, но я все равно решил написать, поскольку столкнулся с той же проблемой. Вот как я это решил.

 $('#alerts-display, #object-display').on('click', ['.item-data-summary', '.item-marker'], function(e) {
    e.preventDefault();

    var id;

    id = setTimeout(() => {
       // code to run here
       return false;
    }, 150);

    timeoutIDForDoubleClick.push(id);
});


$('.panel-items-set-marker-view').on('dblclick', ['.summary', '.marker'], function(e) {
    for (let i = 0; i < timeoutIDForDoubleClick.length; i++) {
       clearTimeout(timeoutIDForDoubleClick[i]);
    }

    // code to run on double click

    e.preventDefault();
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...