Как различить одно нажатие и событие двойного щелчка?

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

1.

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

2.

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

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

Ответ 1

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

Вот трюк:

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

EDIT:

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

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

Ответ 2

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

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

  • MouseDown
  • MouseUp
  • выберите
  • MouseDown
  • MouseUp
  • выберите
  • DblClick

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

  • MouseDown
  • MouseUp
  • выберите
  • MouseUp
  • DblClick

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

Ответ 3

Простая функция. Никакой 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>

Ответ 4

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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

Вместо того, чтобы использовать больше специальных состояний и 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

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

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

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

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

Ответ 8

Другое простое решение 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);

Ответ 9

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

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

Ответ 10

Здесь альтернатива кода 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.

Ответ 11

Я написал простой плагин jQuery, который позволяет использовать пользовательское событие "singleclick", чтобы разделить один клик с двойным щелчком:

https://github.com/omriyariv/jquery-singleclick

$('#someDiv').on('singleclick', function(e) {
    // The event will be fired with a small delay.
    console.log('This is certainly a single-click');
}

Ответ 12

Как отличить одиночные клики от двойных кликов на одном и том же элементе?

Если вам не нужно смешивать их, вы можете положиться на click и dblclick и каждый dblclick справится со своей задачей.

При попытке смешать их возникает проблема: событие dblclick фактически также инициирует событие click, поэтому вам необходимо определить, является ли одиночный щелчок "автономным" одиночным щелчком или частью двойного щелчка.

Кроме того: вы не должны использовать и click и dblclick для одного и того же элемента:

Нецелесообразно привязывать обработчики к событиям click и dblclick для одного и того же элемента. Последовательность запускаемых событий варьируется от браузера к браузеру, причем некоторые из них получают два события щелчка до dblclick, а другие - только одно. Чувствительность к двойному щелчку (максимальное время между щелчками, определяемое как двойной щелчок) может варьироваться в зависимости от операционной системы и браузера и часто настраивается пользователем.
Источник: https://api.jquery.com/dblclick/

Теперь о хороших новостях:

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

Проблема остается в обнаружении одиночных щелчков и в том, являются ли они частью двойного щелчка. Для этого мы вернулись к использованию таймера и setTimeout.

Оборачивая все это вместе с использованием атрибута данных (чтобы избежать глобальной переменной) и без необходимости самостоятельно подсчитывать количество кликов, мы получаем:

HTML:

<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>

<div id="log" style="background: #efefef;"></div>

JavaScript:

<script>
var clickTimeoutID;
$( document ).ready(function() {

    $( '.clickit' ).click( function( event ) {

        if ( event.originalEvent.detail === 1 ) {
            $( '#log' ).append( '(Event:) Single click event received.<br>' );

            /** Is this a true single click or it it a single click that part of a double click?
             * The only way to find out is to wait it for either a specific amount of time or the 'dblclick' event.
             **/
            clickTimeoutID = window.setTimeout(
                    function() {
                        $( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
                    },
                    500 // how much time users have to perform the second click in a double click -- see accessibility note below.
                );

        } else if ( event.originalEvent.detail === 2 ) {
            $( '#log' ).append( '(Event:) Double click event received.<br>' );
            $( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
            window.clearTimeout( clickTimeoutID ); // it a dblclick, so cancel the single click behavior.
        } // triple, quadruple, etc. clicks are ignored.

    });

});
</script>

Демо-версия:

JSfiddle


Примечания о доступности и скорости двойного щелчка:

  • Как говорит Википедия: "Максимальная задержка, необходимая для того, чтобы два последовательных клика интерпретировались как двойной щелчок, не стандартизирована".
  • Нет способа определить скорость двойного щелчка в браузере.
  • Кажется, по умолчанию 500 мс и диапазон 100-900 мм в Windows (источник)
  • Подумайте о людях с ограниченными возможностями, которые в своих настройках ОС устанавливают скорость двойного щелчка до самой низкой.
    • Если скорость двойного щелчка системы ниже, чем наша стандартная настройка на 500 мс выше, будут активированы оба варианта single- и двойной щелчок.
    • Либо не используйте полагаться на комбинированный одиночный и двойной щелчок на одном и том же предмете.
    • Или: добавьте параметр в параметры, чтобы иметь возможность увеличить значение.

Потребовалось время, чтобы найти удовлетворительное решение, надеюсь, это поможет!

Ответ 13

Мне нравится избегать jquery (и других 90-140k lib), и, как отметили браузеры, сначала обработайте onclick, так что вот что я сделал на созданном мной веб-сайте (этот пример также охватывает получение локального местоположения xy) p >

clicksNow-0; //global js, owell

function notify2(e, right) {  // called from onclick= and oncontextmenu= (rc)
var x,y,xx,yy;
var ele = document.getElementById('wrap');  
    // offset fixed parent for local win x y
var xxx= ele.offsetLeft;
var yyy= ele.offsetTop;

//NScape
if (document.layers || document.getElementById&&!document.all) {
    xx= e.pageX;
    yy= e.pageY;
} else {
    xx= e.clientX;
    yy= e.clientY;
}
x=xx-xxx;
y=yy-yyy;

clicksNow++;
    // 200 (2/10ths a sec) is about a low as i seem to be able to go
setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200);
}

function processClick(right, x, y) {
if (clicksNow==0) return; // already processed as dblclick
if (clicksNow==2) alert('dbl');
clicksNow=0;
    ... handle, etc ...
}

надеюсь, что поможет

Ответ 14

это сработало для меня -

var clicked=0;
function chkBtnClcked(evnt) {
    clicked++;
    // wait to see if dblclick
    if (clicked===1) {
        setTimeout(function() {
            clicked=0;
            .
            .
        }, 300); // test for another click within 300ms
    }
    if (clicked===2) {
        stopTimer=setInterval(function() {
            clicked=0;
            .
            .
        }, 30*1000); // refresh every 30 seconds
    }
}

usage-

<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)"  title="Click for next pic; double-click for slide show"></div>

Ответ 15

Просто разместите собственный HTML-ответ на тот случай, если вам понадобится простой и HTML-код.

<p ondblclick="myFunction()" id = 'id'>Double-click me</p>

У этого, конечно, есть нативные параметры Jquery. то есть... $('#id').attr('ondblclick',function(){...}) или, как указано ранее, $('#id').dblclick(function(){...});