Как различить событие одного клика и событие двойного клика? - PullRequest
97 голосов
/ 31 марта 2011

У меня есть одна кнопка в li с идентификатором "my_id". Я прикрепил two jquery события с этим элементом

1

$("#my_id").click(function() { 
    alert('single click');
});

2.

$("#my_id").dblclick(function() {
    alert('double click');
});

Но каждый раз это дает мне single click

Ответы [ 13 ]

75 голосов
/ 01 апреля 2011

Поведение события dblclick объясняется в Quirksmode .

Порядок событий для dblclick:

  1. mousedown
  2. mouseup
  3. click
  4. mousedown
  5. mouseup
  6. click
  7. dblclick

Единственным исключением из этого правила является (конечно) Internet Explorer с их пользовательским порядком:

  1. mousedown
  2. mouseup
  3. click
  4. mouseup
  5. dblclick

Как видите, прослушивание обоих событий вместе на одном элементе приведет к дополнительным вызовам вашего обработчика click.

59 голосов
/ 31 марта 2011

Вам нужно использовать тайм-аут, чтобы проверить, есть ли еще один щелчок после первого щелчка.

Вот трюк :

// Author:  Jacek Becela
// Source:  http://gist.github.com/399624
// License: MIT

jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
  return this.each(function(){
    var clicks = 0, self = this;
    jQuery(this).click(function(event){
      clicks++;
      if (clicks == 1) {
        setTimeout(function(){
          if(clicks == 1) {
            single_click_callback.call(self, event);
          } else {
            double_click_callback.call(self, event);
          }
          clicks = 0;
        }, timeout || 300);
      }
    });
  });
}

Использование:

$("button").single_double_click(function () {
  alert("Try double-clicking me!")
}, function () {
  alert("Double click detected, I'm hiding")
  $(this).hide()
})
<button>Click Me!</button>

РЕДАКТИРОВАТЬ:

Как указано ниже, предпочтите использовать собственное событие dblclick: http://www.quirksmode.org/dom/events/click.html

Или то, которое предоставлено jQuery: http://api.jquery.com/dblclick/

24 голосов
/ 16 апреля 2013

Простая функция.Никаких jquery или других фреймворков не требуется.Передайте свои функции в качестве параметров

<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
    <script>
        function doubleclick(el, onsingle, ondouble) {
            if (el.getAttribute("data-dblclick") == null) {
                el.setAttribute("data-dblclick", 1);
                setTimeout(function () {
                    if (el.getAttribute("data-dblclick") == 1) {
                        onsingle();
                    }
                    el.removeAttribute("data-dblclick");
                }, 300);
            } else {
                el.removeAttribute("data-dblclick");
                ondouble();
            }
        }
    </script>
13 голосов
/ 31 марта 2011

Боюсь, что поведение зависит от браузера:

Не рекомендуется привязывать обработчики к события click и dblclick для тот же элемент. Последовательность вызванные события зависит от браузера в браузер, причем некоторые получают два нажмите события до dblclick и другие только одни. Двойной щелчок чувствительность (максимальное время между клики, которые определяются как двойные нажмите) может варьироваться в зависимости от операционной системы и браузер, и часто настраивается пользователем.

http://api.jquery.com/dblclick/

Запуская ваш код в Firefox, alert () в обработчике click() не позволяет вам щелкнуть второй раз. Если вы удалите такое предупреждение, вы получите оба события.

10 голосов
/ 31 марта 2011

Ну, чтобы дважды щелкнуть (дважды щелкнуть), сначала нужно щелкнуть один раз. Обработчик click() срабатывает при первом щелчке, а поскольку всплывает предупреждение, у вас нет возможности сделать второй щелчок, чтобы запустить обработчик dblclick().

Измените ваши обработчики, чтобы они делали что-то отличное от alert(), и вы увидите поведение. (возможно, изменить цвет фона элемента):

$("#my_id").click(function() { 
    $(this).css('backgroundColor', 'red')
});

$("#my_id").dblclick(function() {
    $(this).css('backgroundColor', 'green')
});
7 голосов
/ 27 декабря 2018

Вместо того, чтобы использовать больше специальных состояний и setTimeout, оказывается, что есть собственное свойство, называемое detail, к которому вы можете обращаться из event объекта!

element.onclick = event => {
   if (event.detail === 1) {
     // it was a single click
   } else if (event.detail === 2) {
     // it was a double click
   }
};

Современные браузеры и даже IE-9 поддерживает это :)

Источник: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail

7 голосов
/ 10 октября 2014

Ни один из этих ответов не удовлетворил мои потребности, поэтому я создал решение, основанное на сути @AdrienSchuler.Используйте это решение только в том случае, если вы хотите привязать один щелчок и двойной щелчок к элементу.В противном случае я рекомендую использовать нативные click и dblclick слушатели.

Это различия:

  • Vanillajs, нет зависимостей
  • Не 't ждать, пока setTimeout обработает обработчик щелчка или двойного щелчка
  • При двойном щелчке он сначала запускает обработчик щелчка, а затем обработчик двойного щелчка

Javascript:

function makeDoubleClick(doubleClickCallback, singleClickCallback) {
    var clicks = 0, timeout;
    return function() {
        clicks++;
        if (clicks == 1) {
            singleClickCallback && singleClickCallback.apply(this, arguments);
            timeout = setTimeout(function() { clicks = 0; }, 400);
        } else {
            timeout && clearTimeout(timeout);
            doubleClickCallback && doubleClickCallback.apply(this, arguments);
            clicks = 0;
        }
    };
}

Использование:

var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));

Ниже приведено использование в jsfiddle, кнопка jQuery - поведение принятого ответа.

jsfiddle

5 голосов
/ 22 марта 2016

Другое простое решение Vanilla, основанное на ответе A1rPun (см. его скрипка для решения jQuery, и оба находятся в этом ).

Похоже, что для того, чтобы НЕ вызывать обработчик одного щелчка, когда пользователь дважды щелкает, обработчик одного щелчка обязательно запускается после задержки ...

var single = function(e){console.log('single')},
    double = function(e){console.log('double')};

var makeDoubleClick = function(e) {

  var clicks = 0,
      timeout;

  return function (e) {

    clicks++;

    if (clicks == 1) {
      timeout = setTimeout(function () {
        single(e);
        clicks = 0;
      }, 250);
    } else {
      clearTimeout(timeout);
      double(e);
      clicks = 0;
    }
  };
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);
4 голосов
/ 04 мая 2016

Вот альтернатива коду jeum для произвольного числа событий:

 var multiClickHandler = function (handlers, delay) {
    var clicks = 0, timeout, delay = delay || 250;
    return function (e) {
      clicks++;
      clearTimeout(timeout);
      timeout = setTimeout(function () {
        if(handlers[clicks]) handlers[clicks](e);
        clicks = 0;
      }, delay);
    };
  }

  cy.on('click', 'node', multiClickHandler({
    1: function(e){console.log('single clicked ', e.cyTarget.id())},
    2: function(e){console.log('double clicked ', e.cyTarget.id())},
    3: function(e){console.log('triple clicked ', e.cyTarget.id())},
    4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
    // ...
  }, 300));

Это необходимо для cytoscape.js приложения.

4 голосов
/ 31 марта 2011

Используйте отличный плагин jQuery Sparkle.Плагин дает вам возможность обнаружить первый и последний клик.Вы можете использовать его, чтобы различать щелчок и щелчок dblclick, определяя, последовал ли за другим щелчком первый щелчок.

Проверьте это на http://balupton.com/sandbox/jquery-sparkle/demo/

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